Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prove June 30th 2015 has 86401 seconds in Java 8 (new Date Time API)?

I try to prove June 30th 2015 has 86401 seconds, use Java code like this:

Instant i1 = Instant.ofEpochSecond(longestDay.toEpochSecond(ZoneOffset.UTC));
Instant i2 = Instant.ofEpochSecond(oneDayAfter.toEpochSecond(ZoneOffset.UTC));
long d = i1.until(i2, ChronoUnit.SECONDS);
System.out.println(d);
// 86400

I try again:

LocalDateTime longestDay = LocalDateTime.of(2015, Month.JUNE, 30, 0, 0, 0);
LocalDateTime oneDayAfter = LocalDateTime.of(2015, Month.JULY, 1, 0, 0, 0, 0);      
long p = ChronoUnit.SECONDS.between(longestDay, oneDayAfter);
System.out.println("p = " + String.valueOf(p));
// Result: p = 86400

still not success

I still try again:

ZonedDateTime startZdt = ZonedDateTime.of( 2015, 06, 30, 23, 59, 59, 00, ZoneOffset.UTC );
ZonedDateTime stopZdt = ZonedDateTime.of( 2015, 07, 01, 00, 00, 00, 00, ZoneOffset.UTC );
long elapsed = startZdt.until( stopZdt,ChronoUnit.SECONDS);
System.out.println("elapsed: " + elapsed);
// Result: elapsed: 1

I can't prove June 30th 2015 has 86401 seconds by Java code. Help me do this!

like image 840
Do Nhu Vy Avatar asked Feb 07 '23 18:02

Do Nhu Vy


1 Answers

Short answer:

No. There is no chance to prove it with java.time (JSR-310) as you have already demonstrated.

Explanation:

  • In order to enable such a feature, there must be at least a leap second table inside the JDK. But: Oracle has decided to remove these data from JDK.
  • I suspect your idea comes from reading the spec of Instant which is talking about the time scale UTC-SLS (originally an expired proposal of Markus Kuhn). UTC-SLS keeps the fiction of having every day 86400 seconds by using a rubber second concept. If you take UTC-SLS seriously then you cannot observe 86401 seconds. Note: UTC-SLS != UTC.
  • However: Due to missing leap second data, UTC-SLS cannot be implemented in Java-8 but only be specified. That practically means, the JSR-310-team wants people to interprete seconds as being on UTC-SLS scale although that scale is surely not the intention of most people when they think of seconds in general. Due to missing data this subtle difference between UTC and UTC-SLS has fortunately no practical relevance in standard Java-8. We can effectively ignore the spec in practice and just handle Instant as being on the same scale as POSIX which totally ignores leap seconds. Also with this view, you only get 86400 seconds.

If you nevertheless want a solution and not ignore leap seconds then the only way to observe 86401 SI-seconds on 2015-06-30 is using an external library like mine (Time4J):

PlainDate ls = PlainDate.of(2015, 6, 30);
Moment start = ls.atStartOfDay().atUTC();
Moment end = ls.plus(1, CalendarUnit.DAYS).atStartOfDay().atUTC();
System.out.println(SI.SECONDS.between(start, end)); // 86401
like image 119
Meno Hochschild Avatar answered Feb 12 '23 09:02

Meno Hochschild