gpt4 book ai didi

c - `gmtime()` 会在闰秒时将秒数报告为 60 吗?

转载 作者:太空狗 更新时间:2023-10-29 16:35:30 30 4
gpt4 key购买 nike

我有一个在 TZ=UTC 运行的服务器,我有这样的代码:

time_t t = time(NULL);
struct tm tm;
gmtime_r(&t, &tm);

问题是 tm.tm_sec == 60 当服务器在闰秒内时?

例如,如果我在以下时间跨度内:

1998-12-31T23:59:60.00 - 915 148 800.00
1998-12-31T23:59:60.25 - 915 148 800.25
1998-12-31T23:59:60.50 - 915 148 800.50
1998-12-31T23:59:60.75 - 915 148 800.75
1999-01-01T00:00:00.00 - 915 148 800.00

gmtime() 会为 time_t = 915148800 返回 tm == 1998-12-31T23:59:60 并且,一旦超出闰秒,返回 tm == 1999-01-01T00:00:00 相同的 time_t?

最佳答案

简短的回答是,不,实际上是 gmtime_r永远不会填写tm_sec与 60。这是不幸的,但不可避免。

根本问题是time_t是,根据 Posix 标准,自 1970-01-01 UTC 假设没有闰秒以来的秒数。

在最近的闰秒中,进程是这样​​的:

1483228799    2016-12-31 23:59:59
1483228800 2017-01-01 00:00:00

是的,应该有闰秒,23:59:60 , 在那里。但是不可能 time_t介于 1483228799 之间的值和 1483228800 .

我知道 gmtime 有两种方法返回以 :60 结尾的时间的变体:

  1. 您可以在 UTC 以外的时间运行操作系统时钟,通常是 TAI 或 TAI-10,并使用所谓的“正确”时区转换为 UTC(或本地时间)进行显示。参见 this web page对此进行一些讨论。

  2. 您可以使用 clock_gettime()并定义一个新的 clkid 值,可能是 CLOCK_UTC ,绕过 time_t使用故意非规范化的问题 struct timespec必要时的值。例如,获取 1483228799 之间的时间值的方法和 1483228800是设置tv_sec1483228799tv_nsec1000000000 .参见 this web page了解更多详情。

方式 #1 工作得很好,但没有人使用它,因为没有人愿意在除了应该的 UTC 以外的任何地方运行他们的内核时钟。 (你最终会遇到文件系统时间戳和嵌入这些时间戳的程序(如 tar)的问题。)

方式 #2 是一个美妙的想法,IMO,但据我所知,它从未在已发布的操作系统中实现。 (碰巧,我有一个适用于 Linux 的工作实现,但我还没有发布我的工作。)要使方法 #2 工作,你需要一个新的 gmtime。变体,也许 gmtime_ts_r , 它接受 struct timespec而不是 time_t .


附录:我刚刚重读了您的问题标题。您问“当服务器处于闰秒时,gmtime() 会报告 60 秒吗?”我们可以回答“是的,但是”,并附上免责声明,因为大多数服务器无法正确表示闰秒期间的时间,它们从不“开启”闰秒。


附录 2:我忘了提到方案 #1 似乎在本地时间更有效——也就是说,当你调用一个 localtime 时变体——比 UTC 时间和 gmtime .很明显 localtime 执行的转换受 TZ 设置的影响环境变量,但不是很清楚 TZgmtime 有任何影响.我观察到一些 gmtime实现受 TZ 影响因此可以根据“正确”区域进行闰秒,而有些则不能。特别是 gmtimeGNU glibc如果 TZ,似乎会注意“正确”区域中的闰秒信息指定一个,而 gmtimeIANA tzcode distribution没有。

关于c - `gmtime()` 会在闰秒时将秒数报告为 60 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48846521/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com