Skip to main content

Appendix D. Leap Seconds (附录 D. 闰秒)

本附录详细说明了 RFC 3339 中闰秒的概念、历史和处理。

What are Leap Seconds? (什么是闰秒?)

偶尔会向协调世界时 (Coordinated Universal Time, UTC) 添加闰秒, 以保持 UTC 与地球自转同步。

Why Leap Seconds? (为什么需要闰秒?)

Atomic Time (原子时, TAI):

  • 基于原子钟, 极其稳定
  • 1 秒 = 9,192,631,770 次铯原子振荡
  • 永不改变

Earth's Rotation (地球自转):

  • 不完全均匀
  • 受潮汐摩擦影响
  • 逐渐减慢 (~每世纪 1.4 毫秒/天)
  • 速率不可预测

How Leap Seconds Work (闰秒如何工作)

Positive Leap Second Example (正闰秒示例)

正常月末:
23:59:58
23:59:59
00:00:00 (下一天)

带正闰秒:
23:59:58
23:59:59
23:59:60 ← 闰秒!
00:00:00 (下一天)

RFC 3339 Representation (RFC 3339 表示)

1990-12-31T23:59:60Z  ✅ 有效 (1990 年 12 月 31 日闰秒)
2012-06-30T23:59:60Z ✅ 有效 (2012 年 6 月 30 日闰秒)
2015-06-30T23:59:60Z ✅ 有效 (2015 年 6 月 30 日闰秒)
2016-12-31T23:59:60Z ✅ 有效 (2016 年 12 月 31 日闰秒)

Historical Leap Seconds (历史闰秒)

自 1972 年引入 UTC 以来:

日期          UTC 时间         TAI-UTC
1972-06-30 23:59:60Z +11s
1972-12-31 23:59:60Z +12s
1990-12-31 23:59:60Z +26s
2012-06-30 23:59:60Z +35s
2015-06-30 23:59:60Z +36s
2016-12-31 23:59:60Z +37s (最近)

注意:

  • 闰秒仅在 6 月 30 日或 12 月 31 日添加
  • 自 1972 年以来已添加 27 个闰秒
  • 最近一次是 2016 年 12 月 31 日

Programming Considerations (编程考虑)

Problem: Most Systems Don't Support Leap Seconds (问题: 大多数系统不支持闰秒)

# 宽松解析闰秒
def parse_rfc3339_with_leap_seconds(timestamp_str):
if ':60' in timestamp_str:
# 将 60 秒替换为 59
timestamp_str = timestamp_str.replace(':60', ':59')
dt = datetime.fromisoformat(timestamp_str.replace('Z', '+00:00'))
return dt + timedelta(seconds=1)
else:
return datetime.fromisoformat(timestamp_str.replace('Z', '+00:00'))

RFC 3339 Specification (RFC 3339 规范)

Syntax Requirement (语法要求)

time-second = 2DIGIT  ; 00-58, 00-59, 00-60 based on leap second rules
  • 秒值可以是 60
  • 仅在月末
  • 必须是已发布的闰秒

Key Point (关键点): RFC 3339 允许闰秒, 但大多数实现为了实际兼容性将它们映射到下一秒。