7

当我使用

  • 用于 TAI或 /usr/share/zoneinfo-leaps的自定义 zoneinfo 文件和
  • 修改后的 NTP 客户端(目前它只增加 27 秒;并等待大约 1 秒的时间戳)

在我的 ArchLinux 机器上,系统时间表现得很好:

> date
Tue Oct 23 17:10:34 TAI 2018
> date -d @1483228827
Sun Jan  1 00:00:00 UTC 2017
> date -d @1483228826
Sat Dec 31 23:59:60 UTC 2016
> date -d @1483228825
Sat Dec 31 23:59:59 UTC 2016

但是:JavaScript 不会:

-阿恩

4

1 回答 1

7

JavaScriptDate对象特别遵循Unix Time的概念(尽管精度更高)。这是 POSIX 规范的一部分,因此有时称为“POSIX 时间”。它不计算闰秒,而是假设每天正好有 86,400 秒。您可以在当前 ECMAScript 规范的第 20.3.1.1 节中了解这一点,其中指出:

自 1970 年 1 月 1 日 UTC 以来,时间在 ECMAScript 中以毫秒为单位进行测量。在时间值中,闰秒被忽略。假设每天正好有 86,400,000 毫秒。

JavaScript 在这方面并不是独一无二的。这是绝大多数其他语言所做的,包括 Python、Ruby、.NET、time_tC 中的典型实现以及许多其他语言。

因为您已更改系统以跟踪 TAI 而不是 UTC,并且在您的系统上实现了该date命令可以理解的闰秒表,所以在您的系统time_t上不是 Unix 时间戳,而是基于 TAI 的变体伪装作为 Unix 时间戳。仅仅因为date命令和其他底层函数认识到这一点,并不意味着它会贯穿您机器上的所有平台和运行时。

事实是,闰秒的不可预测性使得它们很难在 API 中使用。人们通常无法传递需要正确解释闰秒表的时间戳,并期望一个系统将它们解释为与另一个系统相同。例如,虽然您的示例时间戳14832288262017-01-01T00:00:00Z您的系统上,但它将被解释为2017-01-01T00:00:26Z基于 POSIX 的系统或没有闰秒表的系统。所以它们不是便携式的。即使在具有完整更新表的系统上,也不知道这些表将来会包含什么(超过 6 个月的 IERS 公告期),因此我无法生成未来的时间戳,而不会有最终更改的风险。

需要明确的是 - 为了在编程语言中支持闰秒,实现必须不遗余力地做到这一点,并且必须做出并不总是可以接受的权衡。尽管有例外,但总体立场是不支持它们——不是因为任何颠覆或积极的反制措施,而是因为正确地支持它们要困难得多。

也就是说,如果你真的关心 JavaScript 中的闰秒,你就有希望。您可以将您的想法添加到TC39 Temporal 提案(我是其中的支持者之一)。这不会改变Date对象的行为 - 已经烘焙了几十年。但是我们正在为 JavaScript 中的日期和时间开发一组新的标准对象,并且希望您的反馈和参与。在问题#54中有一个线程,我们一直在考虑闰秒可能成为其中一部分的各种方式. 目前,我们还没有对基于 TAI 的系统进行过多思考。如果这是您有经验的领域,请在此处添加您的想法。请记住,我们需要在这与社区的一般需求之间取得平衡,但我们希望得到您的想法。谢谢!

于 2018-10-27T23:48:28.450 回答