Have You Seen This Class?
interface Clock {
long now();
}
class SystemClock implements Clock {
public long now() { return System.currentTimeMillis(); }
}
mysql-eventstore (Clock
, also () => DateTime
)
TIM Ideas (TimeService
)
TIM Ideas - EquitiesBackfill (Clock
)
Merc, DataScopeWrapper (TimeService
)
Investor (Clock
, also () => LocalDateTime
)
Spread amongst our projects, I've found variations on interfaces or raw functions providing DateTime, Date, Instant, LocalDateTime etc.
Need to convert between them to use libraries. Or configure them separately, and lose the "single source of time".
There is in fact a standard abstract clock class and concrete implementations, since Java 8:
abstract class java.time.Clock {
abstract Instant instant();
abstract ZoneId getZone();
abstract Clock withZone(ZoneId z);
long millis() { ... };
static Clock systemDefaultZone();
static Clock systemUTC();
}
A JSR310 (java.time) clock provides:
System::currentTimeMillis
)ZoneId::systemDefault
)By convention, every temporal type has now
static methods, one of which will take a clock:
Instant now = Instant.now(clock); // or just clock.instant()
LocalDate today = LocalDate.now(clock);
OffsetDateTime nowFields = OffsetDateTime.now(clock);
Typically, there will be a now()
method that simply does now(Clock.systemDefaultZone())
But if you're not using the java.time classes, how is this helpful? We mainly still use Joda-Time, and only opportunistically upgrade.
Even so, we might already start producing libraries that use java.time types and expect to share a Clock with their clients.
So eventually, we now have a common clock class to share between projects, which produces Joda-Time types, but is also a JSR310 Clock:
abstract class JodaClock extends java.time.Clock {
Instant now();
DateTime nowDateTime();
LocalDate today();
DateTimeZone getDateTimeZone();
JodaClock withZone(DateTimeZone z);
static JodaClock getDefault(); // getDefault().now() equiv Instant.now()
static JodaClock using(Clock c);
}
JodaClock.getDefault
produces a JodaClock that reads the time and zone from Joda-Time's static settings.
JodaClock.using
, for example to pass this to a library requiring a JodaClock.Available as both pure JSR310 clocks and as JodaClocks:
ManualClock
|ManualJodaClock
SupplierClock
|SupplierJodaClock
LatchableClock
|LatchableJodaClock