正确处理闰秒



在闰秒之前和期间,调用new Date()将返回两次23:59:59(一次在闰秒前,一次在飞跃秒期间),而不是23:59:50和23:59:60。

有没有一种方法(除了在应用程序中实现NTP客户端,或者检查时钟是否倒退或重复)来确定给定的一秒是否是闰秒,以便正确地向用户呈现23:59:60?

就这一点而言,主机操作系统是否有任何挂钩来确定它是在闰秒之前还是之后?

让我们看看java.util.Date:的源代码

public Date() {
    this(System.currentTimeMillis());
}

所以这个问题可以理解为:

System.currentTimeMillis()会产生闰秒值60甚至61吗(正如规范所说)?

答案是严格意义上的:这取决于底层操作系统。但事实是:所有众所周知的操作系统,如Windows、Linux、苹果、安卓,都对闰秒一无所知。相反,这些操作系统在任何时候都会进行任何时钟操作(设置等,与NTP-server同步…)。因此,使用Date-API时不会出现闰秒顺便说一句,值61是不可能的,因为UTC标准规定UTC与UT1的偏差永远不会超过0.9秒,因此不会插入双闰秒。

"61"的起源只是对早期POSIX规范的一个严重误解(这个错误现在已经纠正)。不幸的是,旧的Java规范至今尚未得到纠正,导致了误解。

关于Java-8:

是的,所谓的"Java时间尺度"被正式指定为UTC-SLS——基于一项过期的提案,该提案的目的是针对NTP服务器的内部实现。在现实世界中不存在UTC-SLS的实现。甚至Java-8也不实现UTC-SLS。两个事实证明了这一说法:

  • Java-8不包含闰秒表(这将是任何UTC SLS实现的基础)。Threeten项目最初持有这样一个,但它被删除了(现在也从后台删除了)。

  • java.util.DateInstant的转换率仅为1:1(请参阅源代码-不考虑精度的毫米与纳米)。请注意,关于所谓的"Java时标",Instant的API中未提及java.util.Date

Java时间刻度用于所有日期时间类。这包括Instant、LocalDate、LocalTime、OffsetDateTime、ZonedDateTime和期间

此外:java.util.Date的起源于1995年(Java发明时),但UTC-SLS是在几年后提出的。

那么,Java-8中剩下的闰秒支持是什么呢?规范中的空话引起了很多混乱,没有别的。

你还能做什么在JDK的范围内什么都没有。您需要的是一个内置闰秒数据的外部第三方库。一个例子是我的库Time4J——请参阅本文。另一个选项可能是带有类UTCInstant的Threeen Extra库。但我还没有测试它转换为java.util.Date(似乎是可疑的?)。

根据Date类的Java8文档,在闰秒期间调用Date将/确实正确返回:60或:61。

所以你什么都不需要做。

不过,它是如何做到这一点有点神秘,因为基础Instant类在一天的最后1000秒内传播闰秒,所以最后的每一秒实际上都有1.001秒长,而你的应用程序不知道它是否在闰秒。

相关内容

  • 没有找到相关文章

最新更新