1

So I have a LocalDateTime parser which accepts a date as a String. I have wrote several tests for it e.g. checking for leap year and some more.

Now I want a JUnit test to check for a leap second. I did some research and found that probably it is not possible with java.time(?). So far I found a suitable date on which a leap second occured.

Here is what I've tried so far:

@Test
@DisplayName("Check for leap second")
void shouldLeapSecondOccurReturnExactlyTwoMinuteSpan() {
    String leapSecond = "2015-06-30T23:59:00+0000";
    String leapSecond2 = "2015-07-01T00:01:00";
    Assertions.assertTrue(DateConvertUtils.parseIso8601ToUTC(leapSecond)
   .isEqual(LocalDateTime.parse(leapSecond2).minusSeconds(120)));
}

While DateConvertUtils contains my above mentioned parser and a custom DateTimeFormatter.

I appreciate any help to the right direction.

internethulk
  • 92
  • 2
  • 15
  • What is `DateConvertUtils`...? – Michael Jan 15 '20 at 16:41
  • 2
    As far as I know, `java.time` will ignore leapseconds, see [How does the (Oracle) Java JVM know a leap second is occurring?](https://stackoverflow.com/questions/30984599/how-does-the-oracle-java-jvm-know-a-leap-second-is-occurring) (see the answer by Basil Bourque). – Mark Rotteveel Jan 15 '20 at 16:51
  • As far as I know, the only leap second support in java.time is that for an `Instant` a leap seoncd can be parsed. For example `Instant.parse("2015-06-30T23:59:60Z")` works (but yeilds `2015-06-30T23:59:59Z` because `Instant` cannot *hold* a leap second). – Ole V.V. Jan 15 '20 at 20:26

1 Answers1

1

Well, leap seconds are ignored by most libraries including java.time-package. My lib Time4J however, supports it. Example using your input:

    String s1 = "2015-06-30T23:59:00+0000";
    String s2 = "2015-07-01T00:01:00"; // no offset information

    ChronoFormatter<Moment> f =
        ChronoFormatter
            .ofMomentPattern(
                "uuuu-MM-dd'T'HH:mm:ss[X]", // optional offset
                PatternType.CLDR, 
                Locale.ROOT, 
                ZonalOffset.UTC); // default offset

    Moment m1 = f.parse(s1);
    Moment m2 = f.parse(s2); // no offset => UTC

    long delta = SI.SECONDS.between(m1, m2);
    System.out.println(delta); // 121

Objects of type Moment can be easily converted to/from java.time.Instant if you are willing to loose the possible leap second information (in case you have 2015-06-30T23:60Z).

Good to know: You really need at least a class connected to UTC timeline. Classes like LocalDateTime have no concept of time zones so they have no connection to UTC and are unusable for determining leap seconds by definition.

More background information can be found in my DZone paper.

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126