java函数系统。currentTimeMillis () 显然返回自 1970 年 1 月 1 日以来的秒数。但是,根据wikipedia.org/wiki/Leap_second,自 1972 年以来已经有 25 个闰秒。这意味着自 1970 年 1 月 1 日以来的实际秒数比简单计算所建议的多 25 秒。系统。currentTimeMillis () 进行天真的计算并忽略闰秒?
5 回答
正式而言,这取决于操作系统和实现——至少对于Date
. 来自以下文档java.util.Date
:
尽管 Date 类旨在反映协调世界时 (UTC),但它可能并不完全如此,这取决于 Java 虚拟机的主机环境。几乎所有现代操作系统都假定在所有情况下 1 天 = 24 × 60 × 60 = 86400 秒。然而,在 UTC 中,大约每隔一两年就会多出一秒,称为“闰秒”。闰秒总是作为一天的最后一秒添加,并且总是在 12 月 31 日或 6 月 30 日。例如,由于添加了闰秒,1995 年的最后一分钟是 61 秒。大多数计算机时钟不够准确,无法反映闰秒的区别。
我怀疑您会发现,尽管您的计算机时钟与 UTC 大致对齐,但这是通过 NTP 或类似的方法定期校正时钟,而不是操作系统真正实现闰秒。
我相信 JRE 库通常会假设 86400 秒。它使生活变得如此简单,如果您无论如何都要纠正不准确的系统时钟,那么您也可以这样纠正闰秒。
您真的想计算出您感兴趣的内容。如果您需要一种使用闰秒来表示日期和时间的方法,那么标准 Java 库可能不适合您。据我所知,即使是JSR-310也不再支持闰秒(这对大多数开发人员来说是一个非常明智的决定)。
POSIX 要求系统时钟不承认闰秒的存在。MS Windows 无法保证系统时钟硬件的质量(或存在),并且回避了 1 秒精度的保证。Java 不能轻易地做任何底层系统拒绝做的事情。操作系统受到国际法规历史的阻碍,这些法规导致一个 IEEE 标准 (PTP) 需要闰秒,而另一个 (POSIX) 标准则拒绝闰秒。
检查是否考虑闰秒的一种简单方法是计算从纪元到当前年份任何一天的 00:00 所经过的秒数。
如果该秒数与 00 模 60 一致,则不考虑闰秒,因为在 2013 年,您的模数应为 25(考虑过去 25 闰秒)。
我在javarepl上做了一个小实验:
java> new Date(1000L * 86400 * (365 * 4 + 1) * 12)
java.util.Date res0 = Mon Jan 01 00:00:00 UTC 2018
如您所见,使用了一个简单的“朴素”算术,它只考虑闰年,而不是闰秒。不会增加或减少额外的秒数。
更新:
新Instant
课程也一样:
java> Instant.ofEpochMilli(1000L * 86400 * (365 * 4 + 1) * 12)
java.time.Instant res0 = 2018-01-01T00:00:00Z
查看 currentTimeMillis() 的 Javadoc,它引用了 Date 类的文档,其中有这样的说法:
尽管 Date 类旨在反映协调世界时 (UTC),但它可能并不完全如此,这取决于 Java 虚拟机的主机环境。几乎所有现代操作系统都假定在所有情况下 1 天 = 24 × 60 × 60 = 86400 秒。然而,在 UTC 中,大约每隔一两年就会多出一秒,称为“闰秒”。闰秒总是作为一天的最后一秒添加,并且总是在 12 月 31 日或 6 月 30 日。例如,由于添加了闰秒,1995 年的最后一分钟是 61 秒。大多数计算机时钟不够准确,无法反映闰秒的区别。
所以回答你的问题:是的,闰秒被考虑在内。