I need to schedule a task in my code at a fixed datetime. For that I'm using a ScheduledExecutorService with the method schedule(Runnable command, long delay, TimeUnit unit);
How can I compute this delay according to leap seconds ?
For the moment I use Duration.between()
but it doesn't seem aware of leap seconds:
ZonedDateTime date1 = ZonedDateTime.of(2015, 06, 30, 23, 59, 59, 000000, ZoneOffset.UTC);
ZonedDateTime date2 = ZonedDateTime.of(2015, 07, 01, 00, 00, 00, 000000, ZoneOffset.UTC);
ZonedDateTime date3 = ZonedDateTime.of(2015, 07, 01, 00, 00, 01, 000000, ZoneOffset.UTC);
System.out.println(Duration.between(date1, date2)); // PT1S
System.out.println(Duration.between(date2, date3)); // PT1S
To support leap seconds you need the ThreeTen-Extra extension jar file. It has dedicated classes for UTC and TAI plus the table of leap seconds.
To calculate the duration, use the dedicated durationUntil() method.
Consider using Quartz with CronTrigger
Using my library Time4J (v3.x works on Java 7 - or Time4A on Android) will give you a complete solution including extensive support for formatting and parsing in different timezones. Examples:
There is even more, namely support for clocks being aware of leap seconds and transfer of leap second data from IANA-TZDB. Examples see my article on DZone. Note that Time4J can fully replace ThreetenBP, but is also interoperable with Java-8 (just change the version to v4.x) and offers many more features which are out of scope of the question here.
Side note: Most people obviously choose ThreetenBP in order to make a future migration to Java-8 easier (just changing some import statements). But the problem in your case is that
Java-standard (any version) itself does not know anything about leap seconds (not even the necessary data).
The proposed other 3rd-party library Threeten-Extra is not working on Java-7. It requires Java-8.
After migration to Java-8, Threeten-Extra seems to present a solution. However, I have now done my own tests and would advise against using that library, see following code:
Leaving aside some obvious limitations in formatting and parsing, the main problem seems to be the confusing handling of time scale definitions. The definition of a second depends here on the context. For example the result "PT10M0.600600601S" is okay if you only consider the transformation using UTC-SLS, but not okay if you consider the whole transformation from POSIX via UTC-SLS to UTC. And as said before, POSIX time is well defined 10 minutes before leap second so any fuzzyness of POSIX during the leap second is no excuse.
Keep in mind that really NOBODY outside of
java.time
-world talks about UTC-SLS which has been an (officially expired) proposal of Markus Kuhn addressing the internal implementation of NTP time servers or OS-kernels. Instead other people and enterprises like Google introduce their own different leap smear implementations. I don't see any future for UTC-SLS.And since
java.util.Date
has nothing to do with UTC-SLS (is much older) but is also well defined for normal timestamps (following UTC-definition of Si-second with the limitation of the leap seconds which are not handled at all), we see here an interoperability problem between outer IT-world (which does not want to know anything about leap seconds or UTC-SLS) and Threeten-Extra which can cause unexpected differences in calculated durations.