Unix时间和闰秒

时间:2013-05-14 09:22:01

标签: shell unix-timestamp leap-second

关于Unix(POSIX)时间,Wikipedia说:

  

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

但Unix date命令似乎并没有真正意识到它们

$ 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 个答案:

答案 0 :(得分:19)

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

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

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

对于它的价值,我从未见过一个同意闰秒的程序员。它们应该被明确废除。

答案 1 :(得分:18)

每天的秒数已修复 Unix timestamps

  

Unix时代的Unix时间数为零,并且增加了   自纪元以来每天恰好86400。

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

答案 2 :(得分:2)

在这里和其他地方,关于leap秒的讨论很多,但这并不是一个复杂的问题,因为它与UTC,GMT,UT1,TAI或其他时间无关。标准。根据定义,POSIX(Unix)时间是由IEEE Std 1003.1“ POSIX”标准available here指定的时间。

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

  

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

该标准明确详细地说明了POSIX时间不包括leap秒,尤其是:

  

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

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

在这个问题的其他地方,@ Pacerier表示POSIX时间确实包含leap秒,并且每个POSIX时间可能对应一个以上的UTC时间。尽管这当然是POSIX时间戳的一种可能解释,但标准并未明确规定。他的论点很大程度上构成了不适用于定义POSIX时间的标准的狡猾词语。

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

  

细分的POSIX时间尽管出现了,但不一定是UTC。

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

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

使用POSIX标准中的明显漏洞,实现有意减慢或加快秒数-以便POSIX时间不再使用SI秒-以便与UTC时间保持同步。阅读该标准很明显,这并不是要这样做的,因为孤立的系统无法做到这一点,因此无法与其他机器进行互操作(它们的时间戳(没有leap秒)意味着与其他机器有所不同(leap秒)。阅读:

  <...也就是说,重要的是,所有符合标准的系统都应将“自纪元以来的536457599秒”解释为1986年12月31日59秒59分23小时,而不考虑系统当前时间的准确性。给出该表达式是为了确保一致的解释,而不是试图指定日历。 [...]此未指定的秒名义上等于持续时间的国际系统(SI)秒。

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

  

请注意,作为实际结果,未指定通过某些外部标准测量的秒数。

因此,实现会滥用此自由,方法是有意将其更改为定义上无法在孤立或不参与的系统之间进行互操作的某种东西。或者,该实现可以简单地重复POSIX时间,就好像没有时间过去一样。有关所有现代实现的详细信息,请参见this Unix StackExchange answer

Phew,那真是令人困惑...一个真正的脑筋急转弯!

答案 3 :(得分:1)

由于其他两个答案都包含许多令人误解的信息,因此我将其抛诸脑后。

托马斯说的是每天固定固定的Unix Epoch时间戳秒数是正确的。这意味着在有a秒的日子中,午夜之前第二个秒(午夜之前UTC分钟的第61秒)被赋予与前一秒相同的时间戳。

如果可以,该时间戳将被“重播”。因此,相同的Unix时间戳将用于两个实际秒。这也意味着,如果您要获得分数unix纪元,则会重复整个一秒。

X86399.0X86399.5X86400.0X86400.5X86400.0X86400.5,然后是X86401.0

因此Unix时间不能明确代表leap秒-second秒时间戳也是前一个实际秒的时间戳。