Understanding Epoch Milliseconds¶
Epoch milliseconds is the time elapsed in milliseconds since midnight January 1st, 1970 in the UTC time zone and is held in a long data type. You might have heard about UNIX time rolling over in 2038 - this does apply to epoch seconds held in a 32-bit integer, but a long value holding epoch milliseconds will only rollover in the year 292278994.
Using epoch milliseconds within a service simplifies date handling logic by removing any need to worry about time zones and other complexities. It is also far more efficient using only 8 bytes of memory compared to Java's LocalDateTime which uses 7 bytes for the time plus 8 bytes for the date on top of a lot of static ints and longs.
The biggest challenge developers typically face with epoch milliseconds is that during debugging you will need to convert the epoch time value to something human readable.
When the service needs to interact with something external – such as a user interface – you can transform the value into a human readable date time in the desired time zone.
Samples of the clocks in use are in GitHub.
Agrona provides two implementations of the Epoch clock interface -
System Epoch Clock¶
The system epoch clock returns the current epoch time in milliseconds as a long. Internally, it returns Java's
It has a default instance, so you do not need to allocate one when using it:
Cached Epoch Clock¶
The cached epoch clock has no clock internally, and you must either
update the time using an external source such as a
advance the time by a given number of milliseconds. Internally it makes use of release ordered semantics.
1 2 3 4
The cached epoch clock can be useful when moving time around multiple objects and want the "time" to remain constant until explictly updating or advancing it.
High resolution clocks¶
Clock precision is impacted by JDK version. Hotspot/OpenJDK 8 offers millisecond level precision, while version 11 and up offers microsecond or lower granularity.
It is not uncommon in finance for clock resolution to be higher precision than a millisecond - for example, firms classed as High Frequency traders are required to keep audit trails at the microsecond resolution under Mifid II. Nanosecond time resolution - as supported by clocks synchornised to external atomic or GPS based clocks - is also used. Some users will provide their own implementation of the
EpochNanoClock as backed by hardware specific to their environment.
Agrona offers the
SystemEpochMicroClock, which implements
EpochMicroClock. Internally, this makes use of
Instant, and does the necessary math to convert it into a long value representing the microseconds since epoch.
Agrona offers the
OffsetEpochNanoClock which both implement
SystemEpochNanoClock uses the same underlying technique as
SystemEpochMicroClock, and returns the nano epoch as derived from
OffsetEpochNanoClock performs sampling of
System.nanoTime() at a defined interval to produce an accurate nano time clock in pure Java. The sampling interval and measurement parameters can be optionally overridden.