Using my Time4J library (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 time zones. Examples:
// Time4J - transformation from old world Moment m1 = TemporalType.JAVA_UTIL_DATE.translate(d1); Moment m2 = TemporalType.JAVA_UTIL_DATE.translate(d2); System.out.println("Time4J - from juDate: " + SI.SECONDS.between(m1, m2)); // 601 // Time4J - programmatical construction of timestamps (like in your example) m1 = PlainTimestamp.of(2012, 6, 30, 23, 50, 0).atUTC(); m2 = PlainTimestamp.of(2012, 7, 1, 0, 0, 0).atUTC(); System.out.println("Time4J - from utc-timestamps: " + SI.SECONDS.between(m1, m2)); // 601 // Time4J - parsing zoned inputs ChronoFormatter<Moment> cf = ChronoFormatter.ofMomentPattern( "d. MMM uuuu HH:mm:ss[XXX]", // optional offset PatternType.CLDR, Locale.ENGLISH, EUROPE.PARIS); // only used if the offset is missing in input m1 = cf.parse("1. Jul 2015 01:50:00"); m2 = cf.parse("1. Jul 2015 09:00:00+09:00"); System.out.println("Time4J - from offsets or zones: " + SI.SECONDS.between(m1, m2)); // 601 // the leap second itself can also be parsed Moment ls = cf.parse("1. Jul 2015 08:59:60+09:00"); // offset of Tokyo System.out.println("leap second in 2015: " + ls); // 2015-06-30T23:59:60Z
There is even more, namely support for hours that know seconds of a jump and the transfer of second second data from IANA-TZDB. See the article on Dzone for examples . Please note that Time4J can completely replace ThreetenBP, but it is also compatible with Java-8 (just change the version to v4.x) and offers a lot more features that are not within the scope of the question here.
Note: Most people obviously choose ThreetenBP to simplify future migration to Java-8 (simply by changing some import statements). But the problem in your case is that
The Java version itself (any version) knows nothing about the seconds of the jump (not even the necessary data).
The proposed other third-party Threeten-Extra library does not work on Java-7. It requires Java-8.
After migrating to Java-8, Threeten-Extra seems to present a solution. However, I now made my own tests and did not recommend using this library, see the following code:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); Date d1 = sdf.parse("2012-06-30T23:50:00Z"); Date d2 = sdf.parse("2012-07-01T00:00:00Z"); System.out.println( "Old world in Posix - ignorant of leap seconds: " + (d2.getTime() - d1.getTime()) / 1000); // 600 (OK, SI-seconds without counting leap second, a limitation of POSIX) Instant instant1 = d1.toInstant(); Instant instant2 = d2.toInstant(); System.out.println( "Java 8 without Threeten-Extra: " + (instant2.getEpochSecond() - instant1.getEpochSecond())); // 600 (obviously using more or less fuzzy "rubber seconds", not SI-seconds) // internally a simple 1:1-mapping of POSIX is applied within 'toInstant()' UtcInstant utc1 = UtcInstant.of(instant1); UtcInstant utc2 = UtcInstant.of(instant2); System.out.println( "Threeten-Extra-impl of UTC-SLS: " + utc1.durationUntil(utc2).getSeconds()); // pitfall, see next output! // 600 (??? - where is the leap second, should be 601 because of original POSIX-input?!) System.out.println( "Threeten-Extra-impl of UTC-SLS: " + utc1.durationUntil(utc2)); // <= printing the duration object // PT10M0.600600601S (OK, here the UTC-SLS-specific fraction of second appears // Reason: Smoothing starts 1000s before leap second) // only offset "Z=UTC+00:00" can be parsed utc1 = UtcInstant.parse("2012-06-30T23:50:00Z"); utc2 = UtcInstant.parse("2012-07-01T00:00:00Z"); System.out.println( "Threeten-Extra-impl of UTC-SLS: " + utc1.durationUntil(utc2).getSeconds()); // 601 (expected, the only way where seconds are really SI-seconds)
Leaving aside some obvious limitations in formatting and parsing, the main problem is the confusing processing of timeline definitions. The definition of the second depends on the context. For example, the result “PT10M0.600600601S” is OK if you are considering only a conversion using UTC-SLS, but not OK if you are considering a whole conversion from POSIX through UTC-SLS to UTC. And, as mentioned earlier, the POSIX time is clearly defined 10 minutes before the second jump, so any blurred POSIX during the jump is no excuse.
Keep in mind that really NOBODY outside java.time -world is talking about UTC-SLS, which was (officially expired) Markus Kuhn's suggestion of addressing the internal implementation of NTP time servers or OS kernels. Instead, other people and businesses, such as Google, are introducing their own options for implementing stroke strokes. I do not see the future for UTC-SLS.
And since java.util.Date has nothing to do with UTC-SLS (much older), but is also well defined for ordinary timestamps (after Si-second's UTC definition with a limit of jump seconds that are not processed at all), we see here is the problem of the interaction between the external IT world (which does not want to know anything about the jump seconds or UTC-SLS) and Threeten-Extra, which can cause unexpected differences in the calculated durations.