Clock

Have You Seen This Class?

interface Clock {
  long now();
}

class SystemClock implements Clock {
  public long now() { return System.currentTimeMillis(); }
}

Found in...

mysql-eventstore (Clock, also () => DateTime)

TIM Ideas (TimeService)

TIM Ideas - EquitiesBackfill (Clock)

Merc, DataScopeWrapper (TimeService)

Investor (Clock, also () => LocalDateTime)

Divergence

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".

Common

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:

  • The current instant (System::currentTimeMillis)
  • The current timezone (ZoneId::systemDefault)

Use with JSR310 types

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())

Without JSR310 types?

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.

Joda Clock

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.

Interchange

To JSR310
Because JodaClock extends Clock, an instance can be passed directly to a library requiring just Clock.
From JSR310
If you have just a Clock, you can wrap Joda-producing functionality around it with JodaClock.using, for example to pass this to a library requiring a JodaClock.

Testing

Available as both pure JSR310 clocks and as JodaClocks:

ManualClock|ManualJodaClock
Construct with initial time and fixed time zone: methods to advance clock by durations
SupplierClock|SupplierJodaClock
Fixed time zone, delegates current time to an instant supplier
LatchableClock|LatchableJodaClock
Can either delegate to another (system) clock or be "latched" to work like a manual clock