技術約9分で読めます

うるう秒は2027年5月20日で終わりそう

いけさん目次

2022年11月の第27回CGPM(国際度量衡総会)がうるう秒の2035年までの廃止を決議し、2026年1月に公開された決議案Cが発効日を2027年5月20日とする案を示した。
採決は2026年10月13日からベルサイユで開かれる第28回CGPMで行われる。

期限の2035年より8年早い前倒しの理由は「負のうるう秒」だ。
地球の自転が速くなっていて、1秒を差し引く負のうるう秒が必要になる確率は、2035年までに30%と見積もられている。
負のうるう秒は1972年の制度開始から一度も実施されたことがない。

うるう秒の仕組み

時刻系何に基づくか性質
TAI(国際原子時)原子時計の積算一定の刻みで進み続ける
UT1(世界時)地球の自転の実測自転のゆらぎでずれる
UTC(協定世界時)TAIと同じ刻み + うるう秒UT1に寄せて運用する

UTCはTAIと同じ1秒の刻みで進みつつ、UT1との差が0.9秒以上にならないよう、1秒を挿入または削除して調整する。
NICT(情報通信研究機構)の解説にあるとおり、パリのIERS(国際地球回転・基準系事業)が調整の要否を決める。

IERSは半年ごとにBulletin Cという通知を出し、次の6月末または12月末にうるう秒を入れるかどうかを予告する。
挿入はこれまで27回、すべて1秒を足す方向だった。
UTC運用開始時にTAIとの差は10秒で、27回の挿入を経て現在は37秒になっている。

日本ではNICTが日本標準時にうるう秒を反映する
最後の実施は2017年1月1日で、午前8時59分59秒と午前9時00分00秒の間に「8時59分60秒」が挿入された。

うるう年はグレゴリオ暦の規則から機械的に計算できるが、うるう秒は地球の自転の実測で決まる。
次に入るかどうかは半年前のBulletin Cまで分からない。

廃止が決まるまで

メートルやキログラムの定義も担う国際度量衡総会が、うるう秒の廃止を決めた。
2022年11月の第27回総会の決議4は、UT1とUTCの差の最大許容値を2035年までに引き上げると定めた。
上限が0.9秒のままなので、1秒単位の挿入がいる。
上限を大きく広げれば挿入は止まる。

2022年の決議に新しい上限値は書かれていない。
少なくとも100年はUTCが連続するような値を選ぶこと、その値と実装計画を国際度量衡委員会が次回総会へ提案することまでが決まっていた。

その提案が決議案Cとして2026年1月13日に公開されている。
上限は3600秒(1時間)で、これで数世紀はUTCが連続する。
発効日の2027年5月20日は、1月30日の改訂で設定された。
第28回CGPMは2026年10月13日から15日にベルサイユで開かれ、この案を採決する。

年月出来事
1972年UTCの現行運用開始。TAIとの差は10秒
2016年12月31日27回目の挿入。TAIとの差が37秒に
2022年11月第27回CGPMが2035年までの上限値引き上げを決議
2026年1月決議案Cが公開。上限3600秒、2027年5月20日発効の案
2026年10月第28回CGPMで決議案Cを採決
2027年5月20日採択されれば、うるう秒のない連続UTCが発効

廃止されてもUTC自体はなくならない。
挿入をやめて、UT1との差が増えていくのを許容する。
決議案Cが10月に採択されれば、2027年5月20日の発効に向けてBIPM(国際度量衡局)やIERS、時刻配信サービスの実装と周知が進む。

うるう秒が起こしてきた障害

廃止の背景には、挿入のたびに起きてきた障害がある。

2012年6月30日の挿入では、Redditが30〜40分止まった。
Metaのエンジニアリングブログによると、時刻の変化がLinuxカーネルの高分解能タイマー(hrtimer)を混乱させ、CPUを使い切って機械がロックした。
Wiredの当時の報道では、Mozilla、Gawker、Foursquare、Yelp、LinkedIn、StumbleUponも障害を報告している。
GawkerはTomcatのWebサーバーがほぼ無応答になり、再起動でしか復旧しなかった。

2017年1月1日の挿入では、CloudflareのDNSが一部の応答を返せなくなった。
事後報告によると、社内DNSソフトウェアのRRDNSはGoで書かれていて、上流サーバーの応答時間を次の形で計測していた。

rtt := time.Now().Sub(start)

うるう秒で時刻が1秒戻り、このrttが負になった。
平滑化を経ても負のままの値が乱数関数rand.Int63n()に渡り、負の引数でpanicした。
panic自体は捕捉されたものの、該当するDNS解決は失敗し、ピーク時で約0.2%のクエリに影響した。
修正の全展開までは6時間45分かかっている。

当時のGoには単調に進む時計を読む方法がなく、time.Now()の差分は時刻が戻れば負になり得た。
この問題はGo 1.9でランタイムがモノトニッククロック(現在時刻の巻き戻しや調整に影響されず、単調に増え続ける経過時間専用の時計)を持つ形で解消された。

スミアという回避策

大手はうるう秒をそのまま受け取るのをやめている。
1秒をステップで挿入する代わりに、長い時間に薄く引き伸ばして時計を少しずつ遅らせる。
これをリープスミアと呼ぶ。

実装引き伸ばす幅
Google24時間前日正午から当日正午(UTC)まで線形
Meta17時間当日0時(UTC)から

Googleは2008年からスミアを使っていて、24時間の線形スミアでは時計の進みが11.6ppm(100万分の11.6)だけ遅くなる。
1秒が約11.6マイクロ秒ずつ長くなり、24時間で合計1秒分になる計算だ。
AWSも同じ24時間方式を採用している。

スミアは自前のシステムを守る一方で、配る時刻は標準から外れる。
スミア中の時計はUTCと最大0.5秒ずれる。
幅が違えば実装同士でも一致しない。
GoogleとMetaのサーバーなら、同じうるう秒を処理している間、互いに違う時刻を返すことになる。

Metaは2022年の記事で、挿入をこれ以上続けるのは害の方が大きいとして、27回で止めるよう主張した。
決議案Cの考慮事項は、事業者ごとに違う回避方法が時刻配信の不整合を生んでいると指摘している。

負のうるう秒

27回の挿入はすべて1秒を足す方向で、引く方向の負のうるう秒は一度もない。
負のうるう秒では23時59分58秒の次が翌日の0時00分00秒になる。

ここ数年、地球の自転は速くなっている。
スクリプス海洋研究所のダンカン・アグニューが2024年3月にNatureへ出した論文は、このままなら2029年までにUTCから1秒を引く調整が必要になると予測した。
グリーンランドと南極の氷の融解を衛星重力計測で追うと、融けた水の分布の変化が自転を遅くしている。
その効果を除くと、地球の核の減速が核以外の部分を一貫して加速させ続けていることがわかる。
2029年は両方の傾向を外挿した予測で、氷の融解が加速していなければ3年早かったという。

決議案Cの考慮事項によると、CCTF(時間周波数諮問委員会)とIERSが2025年3月に開いたワークショップは、負のうるう秒の確率が近い将来急速に高まり、2035年までに30%に達すると見積もった。
決議案Cは、対策には時刻同期に依存する産業で2000年問題への準備と同規模の投資がいるとも書いている。

2029年の予測は、2022年決議の期限だった2035年より前だ。
決議案Cの発効日はさらに前の2027年5月20日だ。
ITU-TやIEEE 1588の作業部会などからも、負のうるう秒の挿入リスクを避けるために連続UTCの実装を前倒しするよう求める声明がBIPMへ寄せられていた。

Metaの記事は負のうるう秒について、大規模にテストされたことがなく、タイマーやスケジューラに依存するソフトウェアへ壊滅的な影響がありうると書いた。

M4 Mac miniに入っているうるう秒

検証環境

項目内容
マシンM4 Mac mini、macOS 26.5.2
確認対象tzdataの/usr/share/zoneinfo/leapseconds、Python 3.14.4

うるう秒の一覧は今もOSに配布されている。
macOSのどこに入っているのか探したら、tzdataの一部だった。

$ tail -8 /usr/share/zoneinfo/leapseconds
Leap	2015	Jun	30	23:59:60	+	S
Leap	2016	Dec	31	23:59:60	+	S
(中略)
#updated 1783323897 (2026-07-06 07:44:57 UTC)
#expires 1814140800 (2027-06-28 00:00:00 UTC)

最終エントリは2016年の大晦日のまま、ファイル自体は2026年7月6日に更新されている。
これはIERSが2026年7月6日付のBulletin C 72で「2026年12月末の挿入なし」を告知したのに追随したもので、有効期限は2027年6月28日に延びた。
挿入が9年半なくても、半年ごとに見送りを確認して期限を延ばすサイクルは回り続けている。
この一覧を実際の時刻合わせでどう使うかはNTPデーモン側の話で、そこまでは追っていない。

一方で、日常的に使う時刻の仕組みには、うるう秒の入る場所がないものがある。
試しにPythonのdatetimeで23時59分60秒を作ろうとすると、はねられる。

>>> datetime(2016, 12, 31, 23, 59, 60)
ValueError: second must be in 0..59, not 60

Unix時刻も1日を常に86400秒として数える。
2017年のうるう秒をまたいで引き算してみると、タイムスタンプは1しか進まない。

2016-12-31T23:59:59Z -> 1483228799
2017-01-01T00:00:00Z -> 1483228800

この間に実際は23時59分60秒があり、2秒経過している。
この1秒をどう処理するかは実装任せで、RFC 7164は同じ秒を2回刻む、時計を止める、スミアで薄めるといった方法を挙げている。
2012年の障害は挿入時のカーネルのタイマーが原因で、2017年の障害は時刻が逆行しない前提のコードが原因だった。

サマータイムは平気でうるう秒が駄目な理由

ずれの幅なら1時間のサマータイムや1日のうるう年の方がずっと大きいのに、RedditやCloudflareは1秒のうるう秒で止まった。

POSIX系のコンピュータは内部の時刻をUTC基準のUnix時刻で持っていて、地方時はそこにタイムゾーンの差分を足して表示している。
サマータイムはこの差分をずらすだけで、Unix時刻は切り替えの瞬間も1秒も飛ばずに進み続ける。
ずらす幅は多くの地域で1時間、ロード・ハウ島のように30分の地域もある。
規則はtzdataに将来の分まで予測として入っていて、採用している地域では毎年2回、実際に切り替わっている。
うるう年で増える2月29日も、分や秒の構造は変えずに暦へ1日足すだけで、Unix時刻の上では他の日と同じ86400秒になる。

うるう秒はこの差分ではなく、UTCそのものに1秒を差し込む。
差し込まれた23時59分60秒は、先ほどのValueErrorと引き算のとおり、Unix時刻では表現できない。
時刻は逆行しない、1分は60秒、タイムスタンプは単調に増えるといった、ソフトウェアが当てにしてきた仮定が成り立たなくなる。

予告から実施までの長さも違う。
サマータイムの将来規則は事前にtzdataへ配っておけるが、うるう秒は地球の自転次第で、確定は半年前のBulletin Cだ。
準備に使えるのはその半年だけで、数年に1回しか通らないコードパスを全世界で一斉にぶっつけ本番で実行する。
1時間の切り替えは採用地域で毎年2回起きていて、1秒の挿入はこの9年半一度も起きていない。