Skip to content

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;
}
}
interface CalendarService {
SysTime now();
}
Implementationnow() returns
SysCalendarThe current UTC time, with fractional seconds zeroed
CalendarMockA 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.

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.

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.