A timestamp expressed in milliseconds since 1.1.1970 UTC is a common way to store timestamps, e.g in Java.
e.g:
long timestampUtc = System.currentTim
My new library Time4J is able to handle leap seconds so this is one of several unique features of this library. I don't know any other library which can do formatting of leap seconds. Concretely about your question in detail:
Your example code using standard Java
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String humanTimeUtc = df.format(new Date(timestampUtc));
System.out.println(humanTimeUtc);
looks in Time4J like:
ChronoFormatter formatter =
ChronoFormatter.setUp(Moment.class, Locale.US)
.addPattern("uuuu-MM-dd HH:mm:ss", PatternType.CLDR)
.build();
Moment timestampUTC = SystemClock.INSTANCE.currentTime();
System.out.println(formatter.format(timestampUTC));
// output: 2014-02-20 14:16:25
a) The time source SystemClock
is based on System.currentTimeMillis()
. This source never counts leap seconds and can also never yield a leap second timestamp - assuming that the underlying OS is leapsecond-unaware. So the output in this example will never display a leap second value of 60.
b) Internally an object of type Moment
both holds a posix-timestamp AND a leapsecond-bit in its state. So by help of an external leapsecond table (which is actually hold in a small file in classpath) every Moment
will correctly display the exact same time even when a system administrator will later update the leapsecond file and insert a new one. This does not affect any Moment
outside of leap seconds hence there is no one-second-off-error. => If you rerun the code after insertion of new leap second then the timestamp of stored moment is still the same. The formatted output does not change which is a good thing.
c) You can construct a Moment
which represent a leap second either by choosing a specialized time source (in the future I deliver a SNTP-client which might be able to track a leap second), or by applying a suitable number of SI-seconds added to a normal Moment
. The formatted output for such a timestamp will indeed display a second value of 60, provided that the leap second table is up-to-date. If you transfer this leapsecond-moment to another JVM by serialization where the leapsecond-table is not up-to-date then it will be handled there as one second off (and if you serialize it back to a properly updated JVM or if the receiver-JVM is properly updated later then the leapsecond will be shown again).
d) Time4J also supports GPS time scale. You can construct a Moment
by giving the elapsed seconds since GPS epoch (1980-01-06 midnight at start) and specifying the GPS time scale. Internally the Moment
converts the data to UTC state which is not lossy provided the leapsecond-table is up-to-date. Of course, if your configuration is not up-to-date and the GPS source emits a number of elapsed seconds representing a leapsecond event then there will be an error one-second-off. In order to avoid such tiny and rare errors because of not properly managed leapsecond tables in client JVMs it might be a good idea to install another mechanism for configuration. Time4J defines a SPI-interface for this purpose.