4

我试图证明 2015 年 6 月 30 日有 86401 秒,使用这样的 Java 代码:

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

我再试试:

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

仍然没有成功

我还是再试一次:

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

我无法通过 Java 代码证明 2015 年 6 月 30 日有 86401 秒。帮我做这个!

4

2 回答 2

5

简短的回答:

java.time不,正如您已经证明的那样,没有机会用 (JSR-310) 来证明它。

解释:

  • 为了启用这样的功能,JDK 内部必须至少有一个闰秒表。但是:Oracle 已决定从 JDK 中删除这些数据
  • 我怀疑您的想法来自阅读Instant关于时间尺度 UTC-SLS 的规范(最初是 Markus Kuhn 的过期提案)。UTC-SLS 通过使用橡胶秒概念保持每天 86400 秒的虚构。如果您认真对待 UTC-SLS,那么您将无法观察到 86401 秒。注意:UTC-SLS != UTC
  • 但是:由于缺少闰秒数据,UTC-SLS 无法在 Java-8 中实现,只能指定. 这实际上意味着,JSR-310 团队希望人们将秒解释为在 UTC-SLS 尺度上,尽管当他们想到一般的秒时,这种尺度肯定不是大多数人的意图。幸运的是,由于缺少数据,UTC 和 UTC-SLS 之间的细微差别在标准 Java-8 中没有实际意义。我们可以在实践中有效地忽略规范,只处理Instant与完全忽略闰秒的 POSIX 相同的规模。同样使用此视图,您只能获得 86400 秒。

如果您仍然想要一个解决方案而不是忽略闰秒,那么在 2015 年 6 月 30 日观察 86401 SI 秒的唯一方法是使用像我这样的外部库(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
于 2016-02-17T19:15:40.343 回答
3

在 Java 中,每一天都有相同的秒数。事实上,大多数操作系统都不支持闰秒,而是将其视为漂移。当你设置为UTC你实际上设置GMT+0

于 2016-02-12T01:38:42.440 回答