--- title: 闰秒 summary: UTC 为何存在阶跃间断,以及内嵌闰秒表如何处理它们。 --- # 闰秒 UTC 通过插入或删除整秒来保持与地球自转接近,而地球自转并不均匀。每次插入都是 UTC 时钟中的阶跃间断。本文档解释该机制,以及内核为避免间断参与运算所采用的约定。 ## 定义 闰秒是国际地球自转与参考系统服务在 Bulletin C 公告中宣布的对 UTC 的一秒调整。该调整使 ```text | UT1 - UTC | < 0.9 s ``` UT1 是由地球自转定义的尺度。地球自转速率并非常数,因此自某历元起经过的秒数与地球转过的角度不会保持同步。闰秒用于弥合这一差距。 ## 数学含义 TAI 与 UTC 之间的偏移是日期的阶跃函数: ```text DTAI(date) = 10 s + N(date) ``` 其中 `N(date)` 是 1972-01-01 至该日期之间插入的闰秒数。内核以 TAI 存储时刻,因此该偏移只在时刻与 UTC 之间转换时应用: ```text tai_mjd = utc_mjd + DTAI(utc_mjd) / 86400 utc_mjd = tai_mjd - DTAI(utc_mjd) / 86400 ``` 第二个关系式需要在 UTC 时刻处的偏移,而该时刻正是待求量,因此查找表中包含近似时刻的区间,并校验结果的自洽性。实现通过定位适用的表项来完成。 插入秒使一个 UTC 日历日包含 86,401 秒。包含插入的分钟从 0 秒运行到 60.999 秒,因此日历值的秒字段可以超过 59。 ## 单位约定 表中为每次插入存储偏移发生变化的约化儒略日,以及变化后的偏移秒数。二者都是精确的,因为约化儒略日就是公告发布值换算得到的天数。 ## 适用边界 表起始于 1972-01-01,即现代 UTC 体系的起点。在此之前偏移不是整数秒,闰秒概念也不适用;此类时刻的转换返回空值。 表止于其中包含的最新一次插入。更晚的时刻使用最后已知偏移转换,在下次插入之前是正确的。需要确知远未来结果的调用方必须将其视为预测。 闰秒原则上可以为负,即删除一秒并使某分钟只有 59 秒,但从未有负插入被宣布。实现把偏移当作带符号数处理,因此负插入也能正确表示,虽然会产生没有第 59 秒的 UTC 分钟。 ## 为什么时刻不以 UTC 存储 以 UTC 存储时刻会使减法在跨越插入时出错。表区域内的两个 UTC 秒在时间上相隔一个刻度,却可能对应 1 秒或 0 秒的经过时间,取决于它们落在阶跃的哪一侧。内核通过在存储时使用 TAI、仅在边界处转换来回避这一问题。见 [[time-scales]]。 ## 与其他方案对比 | 方案 | 经过时间精确 | 与民用时间一致 | 处理插入 | 此处采用 | |------|--------------|----------------|----------|----------| | 存储 TAI,边界处转换 | 是 | 显示时一致 | 是,依据表 | 是 | | 存储 UTC,直接相减 | 否 | 是 | 在阶跃处不正确 | 否 | | 存储距固定历元的 TAI 秒 | 是 | 需要转换 | 是,依据表 | 用于时长 | | 忽略闰秒,使用固定偏移 | 是 | 否,最大差一分钟 | 否 | 否 | | 全程使用 UT1 | 对自转是 | 否 | 不适用 | 否 | ## 来源 - 闰秒公告:IERS Bulletin C。 - 偏移历史:随公告发布的表,由 `apsis-leap` 内嵌。 ## 另见 - [[time-scales]]:各尺度与存储约定 - [[calendar-and-mjd]]:日期转换