メインコンテンツまでスキップ

Appendix D. Leap Seconds (閏秒)

この付録では、RFC 3339における閏秒の概念、歴史、および取り扱いについて詳しく説明します。

閏秒とは?

閏秒は、UTCを地球の自転と同期させるために、時折協定世界時(UTC)に追加される1秒です。

なぜ閏秒が必要か?

原子時(TAI):

  • 原子時計に基づく、非常に安定
  • 1秒 = 9,192,631,770回のセシウム原子振動
  • 決して変化しない

地球の自転:

  • 完全に均一ではない
  • 潮汐摩擦などの影響を受ける
  • 徐々に遅くなる(1世紀あたり約1.4ms/日)
  • 速度は予測不可能

閏秒の仕組み

正の閏秒の例

通常の月末:
23:59:58
23:59:59
00:00:00 (次の日)

正の閏秒がある月末:
23:59:58
23:59:59
23:59:60 ← 閏秒!
00:00:00 (次の日)

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日に閏秒)

歴史的閏秒

1972年のUTC導入以来:

日付          UTC時刻         TAI-UTC
1972-06-30 23:59:60Z +11秒
1972-12-31 23:59:60Z +12秒
1990-12-31 23:59:60Z +26秒
2012-06-30 23:59:60Z +35秒
2015-06-30 23:59:60Z +36秒
2016-12-31 23:59:60Z +37秒(最新)

注記:

  • 閏秒は6月30日または12月31日にのみ追加
  • 1972年以降27回の閏秒
  • 最新は2016年12月31日

プログラミング上の考慮事項

問題:ほとんどのシステムは閏秒をサポートしていない

# 閏秒の寛容な解析
def parse_rfc3339_with_leap_seconds(timestamp_str):
if ':60' in timestamp_str:
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仕様

構文要件

time-second = 2DIGIT  ; 00-58, 00-59, 00-60 based on leap second rules
  • 秒の値は60であることができます(MAY)
  • 月末でのみ
  • 公表された閏秒でなければならない

重要ポイント: RFC 3339は閏秒を許可していますが、ほとんどの実装は実用的な互換性のために次の秒にマッピングします。