说道闰秒,可能很多人没有听说过,而闰年和闰月应该被很多人熟知。
闰年是指该年有366日,即较平常年份多出一日。闰年是为了弥补因人为历法规定的年度天数365日和平均回归年的大约365.24219日的差距而设立的。不同历法有不同置闰方法。儒略历每4年置1闰日,平均1年是365.25日。格里高利历每400年少3次闰日,平均是365.2425日。多出来的一天为2月29日。(参考:https://zh.m.wikipedia.org/zh-sg/%E9%97%B0%E5%B9%B4)
我们生活里说的闰月通常是指农历(阴阳历)的闰月。闰月没有固定是一年的中的哪一个月,是动态的,总的规则是19年加7个闰月,即“19年7闰法”。(参考:http://www.gov.cn/govweb/fwxx/kp/2009-06/16/content_1341232.htm)
那什么是闰秒呢?
为确定时间,世界上有两种常用的时间计量系统:基于地球自转的世界时(UT)(参考:https://zh.wikipedia.org/zh-sg/%E4%B8%96%E7%95%8C%E6%97%B6
)和基于原子振荡周期的国际原子时(TAI)(参考:https://zh.wikipedia.org/zh-sg/%E5%9C%8B%E9%9A%9B%E5%8E%9F%E5%AD%90%E6%99%82)。由于两种测量方法不同,随着时间推移,两个计时系统结果会出现差异,因此有了协调世界时的概念。
协调世界时以国际原子时秒长为基础,在时刻上尽量接近世界时。1972年的国际计量大会决定,当国际原子时与世界时的时刻相差达到0.9秒时,协调世界时就增加或减少1秒,以尽量接近世界时,这个修正被称作闰秒。
闰秒实际上是为适应地球自转的脚步而对国际原子时的人为增减。依据国际地球自转服务组织对国际原子时与世界时的监测数据,当两者之差达到0.9秒时,该机构就向全世界发布公告,在下一个6月或12月最后一天的最后一分钟,实施正闰秒或负闰秒。
自1972年协调世界时正式使用至今,全球已经实施了27次正闰秒调整,最近一次的闰秒调整是格林尼治时间2016年12月31日。从协调世界时正式使用以来,地球自转一直处于不断减慢的趋势,因此迄今为止的闰秒都是正闰秒,但相关科研发现,自2020年年中以来,地球自转速率呈现加快趋势,这意味着未来也可能会出现负闰秒。(参考:闰秒是什么,将何去何从 http://www.news.cn/tech/2022-11/19/c_1129142173.htm)
历史上已实行的闰秒日期 | ||
年 | 6月30日 | 12月31日 |
1972年 | +1 | +1 |
1973年 | 0 | +1 |
1974年 | 0 | +1 |
1975年 | 0 | +1 |
1976年 | 0 | +1 |
1977年 | 0 | +1 |
1978年 | 0 | +1 |
1979年 | 0 | +1 |
1980年 | 0 | 0 |
1981年 | +1 | 0 |
1982年 | +1 | 0 |
1983年 | +1 | 0 |
1984年 | 0 | 0 |
1985年 | +1 | 0 |
1986年 | 0 | 0 |
1987年 | 0 | +1 |
1988年 | 0 | 0 |
1989年 | 0 | +1 |
1990年 | 0 | +1 |
1991年 | 0 | 0 |
1992年 | +1 | 0 |
1993年 | +1 | 0 |
1994年 | +1 | 0 |
1995年 | 0 | +1 |
1996年 | 0 | 0 |
1997年 | +1 | 0 |
1998年 | 0 | +1 |
1999年 | 0 | 0 |
2000年 | 0 | 0 |
2001年 | 0 | 0 |
2002年 | 0 | 0 |
2003年 | 0 | 0 |
2004年 | 0 | 0 |
2005年 | 0 | +1 |
2006年 | 0 | 0 |
2007年 | 0 | 0 |
2008年 | 0 | +1 |
2009年 | 0 | 0 |
2010年 | 0 | 0 |
2011年 | 0 | 0 |
2012年 | +1 | 0 |
2013年 | 0 | 0 |
2014年 | 0 | 0 |
2015年 | +1 | 0 |
2016年 | 0 | +1 |
2017年 | 0 | 0 |
2018年 | 0 | 0 |
2019年 | 0 | 0 |
2020年 | 0 | 0 |
2021年 | 0 | 0 |
2022年 | 0 | |
总计 | 11 | 16 |
27 | ||
目前TAI与UTC秒差 | ||
37 |
之前我有写过关于monotonic clock的内容。当时就提到闰秒,正的闰秒会导致wall clock比较时出现负值,所以我们需要使用monotonic clock来克服这一个问题。那为什么呢?我们来看看目前如何处理正值的闰秒的,1998-12-31日的闰秒为例:
TAI (1 January 1999) | UTC (31 December 1998 to 1 January 1999) | Unix time |
1999-01-01T00:00:30.00 | 1998-12-31T23:59:59.00 | 915148799.00 |
1999-01-01T00:00:30.50 | 1998-12-31T23:59:59.50 | 915148799.50 |
1999-01-01T00:00:31.00 | 1998-12-31T23:59:60.00 | 915148800.00 |
1999-01-01T00:00:31.50 | 1998-12-31T23:59:60.50 | 915148800.50 |
1999-01-01T00:00:31.75 | 1998-12-31T23:59:60.75 | 915148800.75 |
1999-01-01T00:00:32.00 | 1999-01-01T00:00:00.00 | 915148800.00 |
1999-01-01T00:00:32.25 | 1999-01-01T00:00:00.25 | 915148800.25 |
1999-01-01T00:00:32.50 | 1999-01-01T00:00:00.50 | 915148800.50 |
1999-01-01T00:00:33.00 | 1999-01-01T00:00:01.00 | 915148801.00 |
可以看到,发生闰秒的1998-12-31 23:59:59之后不是1999年1月1日00:00:00,而是中间多了一个1998-12-31 23:60:60,这两秒的Unix timestamp是一样的。所以如果在使用毫秒级、微秒级、纳秒级的时间戳时,在这两秒里就可能出现负的时间戳差值,比如:23:59:59.600 ~ 23:60:60.000,差值就是一个负值。
写在最后,使用闰秒这种处理方法已被证明具有破坏性,特别是在二十一世纪,尤其是在依赖精确时间戳或时间关键程序控制的服务中。相关国际标准机构一直在讨论是否继续这种做法。(参考:https://zh.wikipedia.org/zh-sg/%E9%97%B0%E7%A7%92)