在闰秒之前和期间,似乎调用new Date()
将返回23:59:59两次(一次在闰秒之前,一次在闰秒期间),而不是23:59:59,和23:59:60。
是否有办法(在应用程序中实现NTP客户端,或检查时钟倒退或重复自身)以确定给定秒是否是闰秒,以便正确呈现23:59:60给用户?
就此而言,主机操作系统是否有任何钩子来确定它是在闰秒之前还是之后?
答案 0 :(得分:6)
让我们看一下java.util.Date
的源代码:
public Date() {
this(System.currentTimeMillis());
}
所以这个问题可以理解为:
System.currentTimeMillis()
会产生闰秒值60甚至61(因为规格假装)?
答案严格来说:它取决于底层操作系统。但事实是:所有众所周知的操作系统,如Windows,Linux,Apple,Android都对闰秒无知。相反,这些操作系统可以随时进行任何时钟操作(返回等,与NTP服务器同步......)。 所以你不会使用Date
- API观察闰秒。顺便说一下,值61是不可能的,因为UTC标准要求UTC永远不会偏离UT1超过0.9秒,结果是不会插入双闰秒。
" 61"的起源从早期的POSIX规范(现在已经纠正了这个错误)只是一个严重的误解。不幸的是,旧的Java规范还没有得到纠正,直到现在才引起误解。
关于Java-8:
是的,所谓的" Java Time-Scale"正式指定为UTC-SLS - 基于过期的提案,其意图主要针对NTP服务器的内部实施。现实世界中不存在UTC-SLS的实现。即使 Java-8也没有实现UTC-SLS 。两个事实证明了这一说法:
Java-8不包含闰秒表(这将是任何UTC-SLS实现的基础)。 Threeten项目最初持有这样一个,但它已被移除(现在也removed from the backport)。
从java.util.Date
到Instant
的转换只是1:1(参见源代码 - 不同的精度毫秒与纳米分开)。请注意,在java.util.Date
的API中未提及Instant
所谓的" Java时间刻度"。
Java时标用于所有日期时间类。这包括 Instant,LocalDate,LocalTime,OffsetDateTime,ZonedDateTime和 持续时间。
此外:java.util.Date
的起源是1995年(当Java被发明时),但UTC-SLS是在几年后提出的。
那么Java-8还剩下什么作为闰秒支持?规范中的空字引起了很多混乱,没有别的。
你还能做什么?在JDK的范围内什么也不做。您需要的是具有内置闰秒数据的外部第三方库。一个例子是我的图书馆Time4J - 见article。另一个选项可能是库Threeten-Extra及其类UTCInstant。但是我没有测试它转换为java.util.Date
(似乎是怀疑?)。
答案 1 :(得分:2)
根据Java8 documentation for the Date class,在闰秒期间调用日期将/正确返回:60或:61。
所以你不需要做任何事情。
它是如何做到这一点有点神秘,因为潜在的Instant class在一天的最后1000秒内传播闰秒 - 因此每个最后几秒实际上将是1.001秒 - 并且你的申请不知道它是否处于闰秒之内。