【问题标题】:where are the leap seconds in javascript?javascript中的闰秒在哪里?
【发布时间】:2018-10-27 07:32:16
【问题描述】:

当我使用时

  • custom zoneinfo file for TAI 或 /usr/share/zoneinfo-leaps 和
  • 修改后的 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 没有:

-阿恩

【问题讨论】:

  • 总是有语言规范,ECMA-262: "自 1970 年 1 月 1 日 UTC 以来,时间在 ECMAScript 中以毫秒为单位。在时间值中,闰秒被忽略。假设有正好是每天 86,400,000 毫秒。"
  • 所以他们实施了防止 JavaScript 使用系统 zoneinfo 的特殊措施?如果是:我们该如何改变呢?
  • 不,他们只是没有做任何特别的事情来包括闰秒。
  • 但是:他们对像我这样的人采取了积极的对策,他们的系统时钟“知道”那 27 个“跳跃”秒……我可以以某种方式关闭这些对策吗?还是我的 JavaScript 不好?
  • 您基于什么假设“主动应对措施”?你检查过其他语言的功能吗?

标签: javascript timezone zoneinfo


【解决方案1】:

JavaScript Date 对象特别遵循Unix Time 的概念(尽管精度更高)。这是 POSIX 规范的一部分,因此有时称为“POSIX 时间”。它不计算闰秒,而是假设每天正好有 86,400 秒。您可以在section 20.3.1.1 of the current ECMAScript specification 中阅读有关此内容的信息,其中指出:

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

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

因为您已将系统更改为跟踪 TAI 而不是 UTC,并且在您的系统上实现了 date 命令可以理解的闰秒表,所以在您的系统上 time_t 不是 Unix 时间戳,而是伪装成 Unix 时间戳的 TAI-based variant。仅仅因为 date 命令和其他底层函数能够识别这一点,并不意味着它可以应用于您机器上的所有平台和运行时。

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

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

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

【讨论】:

  • 1.在多台计算机上运行的应用程序应使用具有相同含义的时间戳(例如(aa)“自 1970 年初以来的 TAI 秒数,但不是闰秒”或(bb)“自 1970 年初以来的 TAI 秒数”)。 2.(aa)如果系统时钟不知道闰秒(这很容易找出......只需要求系统使用 gmtime() 分解 1483228826 并查看秒数)然后应用程序可以拒绝运行或使用(对用户透明)更复杂的代码。
  • 1.如果有人说,我们在 1970 年初之后的 1856149396 TAI 秒见面,那么据我们今天所知,这将是“2028-10-26T05:02:49UTC”。但由于闰秒,UTC 时间字符串可能会更改为“2028-10-26T05:02:39UTC”,直到会议时间临近。 2. 如果有人真的想在“2028-10-26T05:02:49UTC”见面,他/她应该将该时间存储为“自某个时间点以来的 TAI 秒数”,因为 UTC 不支持这一点,因为它在某些(甚至可能是未知和不可预测的)时间点出现异常。
  • 我也在那里评论了那个问题 #54:github.com/tc39/proposal-temporal/issues/…
猜你喜欢
  • 2015-11-12
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 2013-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多