Calendar
crate.calendar is a one-method seam over the system clock. Code that reads the time through it can be tested at a fixed instant instead of racing the real clock.
import crate.calendar;
class TokenIssuer { private CalendarService calendar;
this(CalendarService calendar = SysCalendar.instance) { this.calendar = calendar; }
SysTime expiry() { return calendar.now + 1.hours; }}CalendarService
Section titled “CalendarService”interface CalendarService { SysTime now();}| Implementation | now() returns |
|---|---|
SysCalendar | The current UTC time, with fractional seconds zeroed |
CalendarMock | A fixed time, parsed from the ISO extended string given to the constructor |
SysCalendar.instance is a process-wide instance created at module construction. Default a constructor parameter to it, as above, so production code needs no wiring and tests can pass a mock.
Why Fractional Seconds Are Dropped
Section titled “Why Fractional Seconds Are Dropped”SysCalendar.now truncates to whole seconds. Most storage backends and wire formats do not round-trip sub-second precision, so a timestamp that keeps it compares unequal to the value that comes back out of the database. Truncating at the source means now() and a stored copy of it are the same value.
Testing
Section titled “Testing”auto calendar = new CalendarMock("2020-01-02T03:04:05Z");
calendar.now.toISOExtString.should.equal("2020-01-02T03:04:05Z");CalendarMock never advances. It answers the same instant for every call, which is what an assertion on an expiry or a duration wants.