51

关于 Unix (POSIX) 时间,维基百科说:

由于它处理闰秒,它既不是时间的线性表示,也不是 UTC 的真实表示。

但是 Unixdate命令似乎实际上并没有意识到它们

$ date -d '@867715199' --utc
Mon Jun 30 23:59:59 UTC 1997
$ date -d '@867715200' --utc
Tue Jul  1 00:00:00 UTC 1997

虽然那里应该有闰秒Mon Jun 30 23:59:60 UTC 1997

这是否意味着只有date命令忽略闰秒,而 Unix 时间的概念没有?

4

4 回答 4

38

每天的秒数由Unix 时间戳固定

Unix 时间编号在 Unix 纪元为零,并且自纪元以来每天正好增加 86400。

所以它不能代表闰秒。操作系统将减慢时钟以适应这种情况。就 Unix 时间戳而言,闰秒根本不存在。

于 2013-05-14T09:24:36.577 回答
30

Unix 时间很容易使用,但有些时间戳不是实时时间,有些时间戳不是唯一时间。

也就是说,有一些重复的时间戳代表两个不同的时间秒,因为在 unix 时间中,第 60 秒可能必须重复自身(因为不可能有第 61 秒)。从理论上讲,它们也可能是未来的差距,因为第六十秒不一定存在,尽管到目前为止还没有发布跳过闰秒。

unix time 的基本原理:它被定义为易于使用。向标准库添加对闰秒的支持非常棘手。例如,您想在数据库中表示 2050 年 1 月 1 日。世界上没有人知道距离该日期还有多少秒是 UTC!日期不能存储为 UTC 时间戳,因为 IAU 不知道在接下来的几十年中我们必须添加多少闰秒(它们和随机的一样好)。那么,当未来任何两个日期之间经过的时间长度直到一两年前才知道时,程序员如何进行日期算术呢?Unix 时间很简单:我们已经知道 2050 年 1 月 1 日的时间戳(即 80 年 * #of seconds in a year)。UTC 一年四季都很难相处,

对于它的价值,我从未遇到过同意闰秒的程序员。它们显然应该被废除。

于 2013-05-14T09:36:33.597 回答
15

这里和其他地方有很多关于闰秒的讨论,但这并不是一个复杂的问题,因为它与 UTC、GMT、UT1、TAI 或任何其他时间标准没有任何关系。根据定义,POSIX (Unix) 时间是由 IEEE Std 1003.1 “POSIX”标准指定的时间,可在此处获得

标准是明确的:POSIX 时间不包括闰秒。

协调世界时 (UTC) 包括闰秒。但是,在 POSIX 时间(自纪元以来的秒数)中,闰秒被忽略(未应用)以提供一种简单且兼容的计算时间差的方法。因此,分解的 POSIX 时间不一定是 UTC,尽管它出现了。

该标准详细说明了 POSIX 时间不包括闰秒,特别是:

实际上不可能要求符合要求的实现必须与任何特定的官方时钟具有固定的关系(考虑孤立的系统,或通过将时钟设置为某个任意时间来执行“重新运行”的系统)。

由于闰秒是由委员会决定的,因此在 POSIX 时间中包含闰秒不仅仅是一个“坏主意”,鉴于该标准允许没有网络访问权限的符合性实现,这是不可能的。

在这个问题的其他地方@Pacerier 说过 POSIX 时间确实包括闰秒,并且每个 POSIX 时间可能对应多个 UTC 时间。虽然这肯定是对 POSIX 时间戳的一种可能解释,但这绝不是由标准指定的。他的论点在很大程度上等同于不适用于定义 POSIX 时间的标准的狡猾的话。

现在,事情变得复杂了。按照标准的规定,POSIX 时间可能不等于 UTC 时间:

因此,分解的 POSIX 时间不一定是 UTC,尽管它出现了。

然而,在实践中,确实如此。为了理解这个问题,你必须了解时间标准。GMT 和 UT1 基于地球在宇宙中的天文位置。TAI 是基于通过物理(原子)反应测量的宇宙中经过的实际时间量。在 TAI 中,每一秒都是一个“SI 秒”,它们的长度完全相同。在 UTC 中,每一秒是 SI 秒,但根据需要添加闰秒以将时钟重新调整到 GMT/UT1 的 0.9 秒内。GMT 和 UT1 时间标准是通过对地球在宇宙中的位置和运动的经验测量来定义的,这些经验测量无法通过任何方式(无论是科学理论还是近似值)来预测。因此,闰秒也是不可预测的。

现在,POSIX 标准还规定,所有 POSIX 时间戳在不同的实现中都是可互操作的(意思相同)。一种解决方案是让每个人都同意每个 POSIX 秒是一个 SI 秒,在这种情况下,POSIX 时间相当于 TAI(具有指定的纪元),除了他们的原子钟之外,没有人需要联系任何人。然而,我们没有这样做,可能是因为我们希望 POSIX 时间戳是 UTC 时间戳。

使用 POSIX 标准中的一个明显漏洞,实现故意减慢或加快秒数 - 以便 POSIX 时间不再使用 SI 秒 - 以便与 UTC 时间保持同步。阅读标准很明显这不是预期的,因为这不能用孤立的系统完成,因此不能与其他机器互操作(它们的时间戳,没有闰秒,对于其他机器来说意味着不同的东西,有闰秒)。读:

[...] 重要的是时间名称和秒的解释,因为 Epoch 值在符合标准的系统中是一致的;也就是说,重要的是,所有符合标准的系统都将“536457599 seconds since the Epoch”解释为 1986 年 12 月 31 日 59 秒 59 分钟 23 小时,而不管系统对当前时间的理解是否准确。给出该表达式是为了确保一致的解释,而不是试图指定日历。[...] 这个未指定的秒在名义上等于国际系统 (SI) 秒的持续时间。

允许这种行为的“漏洞”:

请注意,作为实际结果,未指定由某些外部标准测量的一秒长度。

因此,实现滥用这种自由,故意将其更改为根据定义不能在隔离或非参与系统之间互操作的东西。或者,实现可以简单地重复 POSIX 次,就好像没有时间过去一样。有关所有现代实现的详细信息,请参阅此 Unix StackExchange 答案。

唷,这很令人困惑......一个真正的脑筋急转弯!

于 2019-10-15T09:10:25.680 回答
6

由于其他两个答案都包含许多误导性信息,因此我将其加入。

Thomas 说得对,每天的 Unix Epoch 时间戳秒数是固定的。这意味着在有闰秒的日子里,午夜前的第二秒(UTC 午夜前的第 61 秒)被赋予与前一秒相同的时间戳。

如果您愿意,该时间戳将被“重播”。因此,相同的 unix 时间戳将用于两个真实世界的秒。这也意味着如果你得到分数 unix 纪元,整个秒都会重复。

X86399.0, X86399.5, X86400.0, X86400.5, X86400.0, X86400.5, 那么X86401.0.

所以unix时间不能明确地表示闰秒——闰秒时间戳也是前一个真实世界秒的时间戳。

于 2019-01-01T22:37:32.940 回答