Skip to content
Published on

2026年も閏秒なし — そして誰も動かしたことのない負の閏秒

シェア
Authors

はじめに — 閏秒、そしてUTCとTAIと地球の自転

ほとんどの開発者は、時間を「ただ均一に流れるもの」と仮定してコードを書きます。しかし私たちが使うUTCは、二つの異なる時間のあいだの妥協物です。一つは原子時計で測る国際原子時(TAI)で、完璧に均一な秒を刻みます。もう一つは地球の自転で定義される天文時(UT1)で、地球は潮汐摩擦や内部の揺らぎのために少しずつぶれ、自転速度が変わります。

UTCはTAIの均一な秒で刻みつつ、UT1から0.9秒以上ずれないように、ときどき1秒を挿入します。この挿入する1秒が閏秒(leap second)です。正の閏秒はこうなります。その日の最後の分が61秒になります。

正の閏秒:   23:59:58 → 23:59:59 → 23:59:60 → 00:00:00

問題の種はここにあります。23:59:60 という時刻は実際に存在しますが、後で見るように、Unix時間にはこれを収める場所がありません。1972年の導入以来、閏秒は27回入り、すべて正の閏秒でした。最後は2016年12月31日です。その結果、現在は TAI - UTC = 37秒、裏返せば UTC - TAI = -37秒 です。

2026年: 閏秒なし、そして史上初の負の閏秒

2026年7月6日、パリでIERSがBulletin C 72を発表しました。核心は一行です。

IERS Bulletin C 72 — Paris, 06 July 2026
"NO leap second will be introduced ... at the end of December 2026."
UTC - TAI = -37 s   (2017-01-01 以降変化なし)

つまり2026年12月にも閏秒はありません(6月末にもありませんでした)。もう何年も調整がないわけですが、これが静かなニュースではない理由があります。2016年頃から、地球の自転はむしろ 速く なり始めました。自転がさらに速まり、UT1がUTCより先に進むと、いつかはUTCから1秒を引いて追いつかせる必要があります。史上初の負の閏秒(negative leap second)を入れる状況です。

負の閏秒は正の閏秒とちょうど逆で、1秒を消します。その日の最後の分は59秒になります。

負の閏秒:   23:59:58 → 00:00:00        (23:59:59 を削除)

これまで27回はすべて正の閏秒で、負の閏秒は規格の上にだけ存在し、地球上のどこでも実際に適用されたことはありません。BIPM時間部門の Patrizia Tavella 氏は「2035年まで待てば、負の閏秒が必要になる確率は30パーセント」と見積もっています。一方、2022年のCGPM決議4号は、閏秒を「2035年またはそれ以前」に事実上廃止し、UT1とUTCの許容誤差をずっと大きくすることを決めました。新しい許容値は2026年10月の第28回CGPMで定められる予定です。しかしこの決定も、2035年までに残る危険を消してはくれません。

なぜ分散システムにとって危険なのか — POSIX時間、NTP、そして2012・2017年の教訓

Unix時間の定義は単純です。unix時間 = (エポック以降の日数) × 86400 + その日の秒 。つまり「1日は必ず 86400 秒」と決め打ちします。だから 23:59:60 を置く場所がありません。

  • 正の閏秒では、Unix系は普通その1秒を繰り返すか、時計を1秒戻します。時間が後戻りするか、同じタイムスタンプが二度現れます(非単調)。
  • 負の閏秒では、タイムスタンプが一つ飛ばされます。時間は依然として前にしか進みませんが、23:59:59 に当たるUnix値はどの実際の瞬間にも対応しない「穴」として残ります。

この仮定が壊れると何が起きるかを、私たちはすでに見ています。2012年7月1日の閏秒では、Linuxカーネルのタイマー(hrtimer)のバグがライブロックを起こし、CPUを100パーセントに張り付かせました。RedditやMozillaなどが影響を受け、Amadeus航空予約システムの障害でQantasの一部の便が遅れました。多くの場合、NTPの再起動や時計のリセットで乗り切りました。

2016年12月31日の閏秒が深夜に適用されると、Goで書かれたCloudflareのDNSリゾルバが「時間は常に前に進む」と仮定して二つの時刻を引き、負の間隔を得ました。その値が乱数範囲の計算に入り、一部のDNS問い合わせがエラーを返しました。Cloudflareはこの事後分析を公開しています。

二つの事件の根は同じです。コードが「時間は均一に、単調に流れる」と信じたことです。ここで一つの逆転があります。負の閏秒は時間を前に飛ばすので、2017年のCloudflare型の「負の間隔」バグはむしろ起きません(単調性は保たれます)。HNのスレッドでも「前に飛ぶのは、後ろに飛んだときのような時間ループを生まない」という指摘がありました。本当の問題は別にあります。負の閏秒の処理経路は、これまでどの本番システムでも一度も実行されたことがないのです。「1分は60秒」、常に +1 だけを仮定するハードコードされた閏秒表、逆方向(時計を速める)に回すスミアのロジックは、すべて検証されていないコードです。

NTP側も同じです。Google、Amazon、Meta は、閏秒を一定の区間にわたって「ならして(smear)」消します(GoogleとAWSは24時間)。だからアプリケーションには 23:59:60 はまったく見えません。しかし区間の長さと曲線は会社ごとに異なり、スミアするサーバとしないサーバを同じ艦隊に混ぜると、時計が食い違います。負の閏秒では、スミアは時計を少し速く回して1秒を回収する必要がありますが、これも大規模に動かしたことはありません。

おわりに — エンジニアが今確認すべきこと

  • 自分のプラットフォームが閏秒をどう扱うかを知っておきましょう。ステップ(step)、繰り返し(repeat)、スミア(smear) のどれか。艦隊全体が同じ方式であるべきで、スミアと非スミアのNTPを混ぜてはいけません。
  • 期間やタイムアウトの計測には、壁時計(CLOCK_REALTIME)ではなく単調時計(CLOCK_MONOTONIC)を使いましょう。2017年のCloudflareのバグは、まさに壁時計の引き算でした。
  • 「1分 = 60秒」「1日 = 86400 秒」「閏秒は常に +1」をコードに埋め込まないこと。
  • 並び順・一意性・順序保証を壁時計のタイムスタンプに頼らないこと。論理時計、単調なソース、TrueTime式の区間を使いましょう。
  • テストしましょう。時計を実際に一つ飛ばせば、負の閏秒を模擬できます。ほとんどの組織は一度もやったことがありません。

正直に言えば、2026年12月には何も起きません(閏秒なし)。この記事の要点は恐怖ではなく準備です。地球の自転はすでに向きを変えており、いつか(おそらく2035年より前に)私たちは、一度も実行されたことのないコード経路を、地球全体で同時に踏むことになります。その前に、壁時計を盲信するコードから洗い出しておくのが賢明です。

参考資料