本文へ移動
雑学書庫好奇心が集まる場所
日本語

時計が1901年に戻る:2038年問題(Year 2038 Problem)

2000年を前に、世界中が「ミレニアムバグ(2000年問題)」で緊張したことを覚えている方も多いでしょう。年を下2桁だけで記録していたプログラムが、2000年を1900年と取り違えるかもしれないという心配でした。ところがコンピュータの世界には、これとよく似たもう一つの日付の問題がまだ残っています。それが「2038年問題(Year 2038 Problem)」です。

2038年問題とは、簡単に言えば、時間を秒単位の数で数えるコンピュータが、2038年1月19日以降の時刻を正しく表せなくなる現象を意味します。数を入れる枠の大きさが決まっているために起こるもので、英語圏ではY2K38や、エポック(epoch)とアポカリプス(apocalypse)を組み合わせた「エポカリプス(Epochalypse)」という愛称でも呼ばれます。

この記事では、コンピュータが時間を数える方法から、2038年問題が起こる仕組み、すでに現れた事例と危険な機器、そしてこれまでに用意された解決策までを順に見ていきます。


時計が逆戻りする日、2038年問題

コンピュータは時間をどう数えるのか

静かなサーバールームに小さなステータスランプがともったコンピュータラックが並び、通路の突き当たりの壁に大きなアナログ時計が掛かっている様子

私たちは日付を年、月、日で書きますが、多くのコンピュータは時間を一つの大きな数として記憶しています。

(1)Unix時間
Unix系のオペレーティングシステムと、その影響を受けた数多くのシステムは、1970年1月1日0時0分0秒(協定世界時)を起点とし、そこから何秒経ったかを数えて時間を表します。この方式を「Unix時間(Unix Time)」といい、起点を「Unixエポック(Unix Epoch)」と呼びます。

(2)一つの数で扱う利点
時間が一つの数にまとまれば、二つの時刻の間隔は引き算一回で求められ、保存や比較も簡単です。そのため、ファイルの作成時刻、ログの記録、予約処理など、時間が必要なあらゆる場所でこの方式が使われてきました。

(3)決まった枠の大きさ
問題は、この数を入れる枠です。長いあいだ多くのシステムがUnix時間を「符号付き32ビット整数」に保存してきましたが、この枠に入れられる最大の数は2,147,483,647です。


2038年問題が起こる仕組み

真鍮の数字車と歯車がかみ合った古い機械式カウンターが一回りして回っていく様子を間近で撮影した場面

決まった枠に数を足し続けると、いつかは枠があふれる瞬間がやって来ます。

(1)最後の1秒
1970年から2,147,483,647秒が経つ時刻は、協定世界時で2038年1月19日3時14分7秒、韓国時間では同じ日の昼12時14分7秒です。32ビットの枠が表せる最後の瞬間がまさにこの時です。

(2)あふれと符号の反転
ここで1秒が加わると、数が枠からあふれて先頭の符号ビットが変わります。これを「整数オーバーフロー(Integer Overflow)」といい、最大の正の数だった値が一瞬で最小の負の数になります。

(3)1901年に戻った時計
負の数になった時間は、起点より前の過去として解釈されます。その結果、システムは今が1901年12月13日だと思い込み、日付で計算する機能がおかしな動きをすることがあります。

ミレニアムバグが年を10進数2桁で記録したせいで起きたのに対し、2038年問題は時間を2進数32桁の枠に入れたせいで起きるという点が異なります。


2038年問題の説明図。POSIX時間は1970年1月1日00時00分00秒UTCを0秒として数える。32ビット符号付きの秒数の最大値2,147,483,647は2038年1月19日03時14分07秒UTCである。次の秒である2,147,483,648はこの時間型の範囲を超え、結果は実装によって異なる。64ビット時間型への移行と、オペレーティングシステム・ライブラリ・アプリ・保存および通信形式の点検が必要である。
POSIX秒を32ビット符号付き整数で保存する場合を説明しています。範囲を超えた場合の結果は実装によって異なり、32ビット機器でも64ビット時間型を使うことができます。資料:GNU C Library, Time Types、Linux man-pages, time(2)、Linux Kernel, ktime accessors。説明図:雑学書庫。

すでに現れた事例と危険な機器

明るい机の上に、アンテナ付きのルーター、小型の防犯カメラ、自動車用の電子制御回路基板が並べて置かれている様子

2038年はまだ来ていませんが、遠い未来の日付を計算するプログラムではすでに問題が表面化しました。

  • Webサーバーのタイムアウト(AOLserver):2006年5月、あるWebサーバープログラムが「決して終わらないはずの」リクエストの期限を10億秒後に設定していたところ、その期限が2038年を超えたことで計算が狂い、停止する事態が起きました。
  • メールサーバーの新年エラー(Exchange Server):2022年1月1日、マイクロソフトのメールサーバープログラムが更新番号を32ビットの数として扱っていたため、その値が上限を超えるとマルウェア検査機能が停止しました。
  • 長く使う組み込み機器(Embedded Systems):自動車のブレーキ装置、ルーター、ネットワークカメラのように、一度設置すると数十年使われ、更新がまれな機器が最も心配な対象とされています。

もちろん、すべての機器が危険なわけではありません。日付を必要としない機器や、二つの時刻の差だけを計算する機器は、大きな問題に直面しないこともあります。


2038年問題を防ぐ方法

明るいオフィスで開発者が2台のモニターを見ながらコードを点検し、キーボードの横に手帳とコーヒーカップが置かれている様子

2038年問題には一度ですべてを直す万能の解決策がないため、いくつもの方法が併用されています。

(1)64ビットに枠を広げる
最も広く使われている方法は、時間を入れる枠を64ビットに広げることです。こうすればオーバーフローが起きるまでに約2,920億年かかり、事実上終わりのない時計になります。64ビットコンピュータ向けのオペレーティングシステムの多くは、すでにこの方式を採用しています。

(2)古い32ビット環境を手直しする
Linuxは2020年の5.6版から32ビット機器でも64ビットの時間を使えるようになり、NetBSDやOpenBSDといったオペレーティングシステムも早くから64ビットの時間へ移行しました。ただし枠の大きさを変えると既存のプログラムと合わなくなることがあるため、慎重に進める必要があります。

(3)残された時間で点検する
オペレーティングシステムが変わっても、その上で動くプログラムやデータベースが相変わらず32ビットの数で時間を扱っていれば、問題は残ります。だからこそ、古いコードや機器を前もって見つけて直す地道な点検が、最も確実な備えになります。


2038年問題は、ごく小さな設計上の選択が数十年後に大きな宿題となって返ってくることがあると示しています。今は十分に見える枠も、時間が積み重なればいつかはあふれることを忘れず、前もって備える姿勢が必要です。

今日の便利な選択が明日の限界になりうると知ること、それが長く使えるシステム設計の第一歩です。