How can a 1 year old (java) lib correctly perform an UTC Time formatting, considering a newly introduced leap second

后端 未结 5 1782

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         


        
5条回答
  •  被撕碎了的回忆
    2021-01-11 10:47

    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.

提交回复
热议问题