Unix时间戳实际跟踪什么?

时间:2018-09-09 09:44:33

标签: python datetime unix-timestamp leap-second

我知道Unix时间戳定义为自1970-01-01 00:00:00Z起经过的秒数。但是,我找不到给出此定义的明确来源。我还阅读了有关UTC和Unix时间戳之间有关leap秒的各种不同陈述。

This wikipedia page包含所有leap秒的列表。第一个是

1972-06-30 23:59:60

关于Unix时间戳的声明

  

至于“所有现代计算机系统”,Unix时间对于秒以外的任何东西都一无所知。

来源:HackerNews, brazzy

  

UNIX时间跟踪UTC而不是TAI,这意味着“校正”了leap秒。结果,UNIX时间不是“自纪元以来的秒数”,而是“ 86400 *(自纪元以来的整天数)+(自午夜以来的秒数)”,并且UNIX时间将向前移动(到目前为止)。在leap秒上向后倒退(在大多数实现中,由于日期从23:59:60到00:00:00,它们具有相同的时间戳,因此会重复一秒)。

来源:Hacker News, masklinn

我也读过(但我找不到它-在堆栈溢出的某个地方),Unix时间戳假定每天正好有24 * 60 * 60秒。张贴者暗示,日期仍然以某种方式保持同步,而the秒只是“减速”了真正的秒。因此,“ unix时间戳秒”可能不是SI秒。

可能的答案

我可以看到三个可能的答案:

A1:Unix时间戳记从1970-01-01 00:00:00Z开始跟踪SI秒。这意味着它们距离UTC的时间为27秒。

A2:Unix时间戳跟踪“在TAI中经过的秒数”。这意味着将Unix时间戳转换为UTC的库必须处理leap秒。

A3:Unix时间戳跟踪“以UTC为单位的秒数”。这意味着在大多数情况下,两个Unix时间戳之间的差异1可能是1 SI秒,但并非全部。

请在答案中添加来源。

Python

Python datetime似乎不知道leap秒(?)。

>>> import datetime
>>> a = datetime.datetime(1972, 6, 30, 23, 59, 59)
>>> b = datetime.datetime(1972, 7, 1, 0, 0, 0)
>>> b-a
datetime.timedelta(0, 1)

time模块似乎在第二秒之前映射了实际的leap秒:

>>> import time
>>> t3 = time.mktime((1972, 6, 30, 23, 59, 59, -1, -1, -1))
>>> t4 = time.mktime((1972, 7, 1, 0, 0, 0, -1, -1, -1))
>>> t4 - t3
1.0
>>> t4 = time.mktime((1972, 6, 30, 23, 59, 60, -1, -1, -1))
>>> t4 - t3
1.0

issue23574支持此印象。

2 个答案:

答案 0 :(得分:2)

  

距大纪元A.4.16秒

     

世界标准时间(UTC)包括leap秒。但是,在POSIX时间(自大纪元以来的秒数)中, le秒被忽略(不应用),以提供一种简便且兼容的计算时差的方法。因此,尽管出现故障,但分解后的POSIX时间不一定是UTC。   [...]

     

大多数系统的“时间”概念是一个不断增加的值,因此即使在seconds秒内该值也应增加。但是,不仅大多数系统不跟踪leap秒,而且大多数系统可能未与任何标准时间参考同步。因此,由于大纪元要精确地表示参考时间与大纪元之间的秒数,因此不宜将时间表示为秒。

     

仅要求允许应用程序将此时间视为代表参考时间和纪元之间的秒数就足够了。系统供应商和系统管理员有责任确保此值尽可能接近在该系统上运行的应用程序所必需的时间,以代表参考时间和纪元之间的秒数。 >

来源: http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16

答案 1 :(得分:0)

Unix 时间跟踪自 1970-01-01 00:00:00 UTC 减去 UTC 的 leap seconds 以来经过的 SI 秒。不计算正闰秒,负闰秒计算两次。换句话说,它就像每天持续 86,400 SI 秒一样计算,因此 86,400 倍数的 Unix 时间对应于 UTC 午夜。

没有闰秒的午夜过渡(UTC 日持续 86,400 SI 秒):

UTC       Second #  Unix time (mod 86,400)
--------  --------  ----------------------
23:59:58  86,398th  86,398
23:59:59  86,399th  86,399
00:00:00  86,400th  86,400

具有正闰秒的午夜过渡(UTC 日持续 86,401 SI 秒);到目前为止已经发生了 27 天:

UTC       Second #  Unix time (mod 86,400)
--------  --------  ----------------------
23:59:59  86,399th  86,399
23:59:60  86,400th  86,399 <- positive leap second: not counted in Unix time
00:00:00  86,401th  86,400

具有负闰秒的午夜过渡(UTC 日持续 86,399 SI 秒);到目前为止从未发生过:

UTC       Second #  Unix time (mod 86,400)
--------  --------  ----------------------
23:59:57  86,397th  86,397
23:59:58  86,398th  86,398 86,399 <- negative leap second: counted twice in
00:00:00  86,399th  86,400           Unix time

有关其他信息,请参阅此 this answer