闰秒和标准::计时

Leap seconds and std::chrono

本文关键字:计时 标准      更新时间:2023-10-16

我看了一眼 cppreference.org(强调我的):

时钟std::chrono::utc_clock是表示协调世界时 (UTC) 的时钟。它测量自 1970 年 1 月 1 日星期四 00:00:00 UTC 以来的时间,包括闰秒

将其与system_clock的定义进行比较:

system_clock测量 Unix 时间(即自 1970 年 1 月 1 日星期四协调世界时 (UTC) 00:00:00 以来的时间,不计算闰秒)。

实际上可以在同一系统中同时使用两者吗?例如,如果系统时钟通过 NTP 同步,则服务器决定它是什么时间,这可能使用闰秒,也可以不使用闰秒,但C++库实现无法知道任何相关信息。或者,标准是否要求在引入闰秒时建立一个数据库?

NTP服务器为您提供UTC(以1900年以来的秒格式)。当前时间,就是当前时间。为了到达那里,有多少闰秒并不重要。

事情变得复杂的地方是当添加闰秒时。NTP将在当下宣布这一点,各种操作系统在内部做各种事情来记录这一点,因为它们倾向于将时间存储为"自纪元以来的秒数" - Linux和Windows不包括闰秒,因为这会使他们的时间戳渲染更加复杂(有多少闰秒?)并且他们无法处理。相反,他们只是在宣布的闰秒附近放慢或加快时钟一段时间,因此他们不是实际记录它,而是调整自己的秒数,以便将该计数渲染为时间戳稍后看起来很准确。

(我不知道的是,操作系统将如何从NTP事务中重新确定其不是真正的秒数,而是从NTP事务中重新确定其秒数,而不知道要扣除多少闰秒;欢迎编辑。

system_clock给你这个秒数,它(在主流平台上)直接来自操作系统(例如time())。

utc_clock给你一个类似的秒数,但一个"真实"的。在这样的主流平台上,这必然是事后添加闰秒的system_clock。这些历史数据也来自系统,实际上是某种数据库(尽管确切的来源取决于实现)。

总之,两个时钟的数据源(略有)不同,因此毫无疑问它们是否可以在同一系统上共存。但是,system_clock可能直接来自您的操作系统,而utc_clock可能没有。

延伸阅读

  • NTP 和闰秒:https://www.meinbergglobal.com/english/info/leap-second.htm#os
  • 新的utc_clock功能及其好友:https://howardhinnant.github.io/date/d0355r4.html

我发现这份工作草案大约是 20 C++的时间,这似乎是在 AD 2020 年发布的。它有一个关于utc_clock的子页面,其中包括以下示例:

clock_­cast<utc_­clock>(sys_­seconds{sys_­days{1970y/January/1}}).time_­since_­epoch() is 0s.
clock_­cast<utc_­clock>(sys_­seconds{sys_­days{2000y/January/1}}).time_­since_­epoch()

并指出最后一个值"是 946'684'822s,即 10'957 * 86'400s + 22s。请注意,10,957 天大约是 30 年,因此 utc_clock 的值显然表示自 1970 年 1 月 1 日 UTC 以来的秒数,其中每个闰秒都会增加 utc_clock 的值。

由于这表示为转换,因此推断转换将调用闰秒表似乎是合理的,即使操作系统没有 UTC 和 TAI 之间的区别概念,也没有包含 61 秒的分钟的概念,也可以执行转换。

我必须承认,我对时间比C++更感兴趣,近20年来我没有写过认真的C++代码。