2038年問題
2038年問題(にせんさんじゅうはちねんもんだい)は、2038年1月19日3時14分7秒(UTC、以下同様)を過ぎると、コンピュータが誤動作する可能性があるとされる年問題。
目次 |
[編集] 経緯
標準的なC言語の実装では、時刻の表現としてUNIX時間《1970年1月1日0時0分0秒からの経過秒数》を使用している。この起点の時刻は、最初にUNIXにそのような機能が実装された時にキリがよかった過去の時刻であり、たまたまそう決めたというだけのものに過ぎない。
この経過秒数を表現する型は、UNIXの仕様では、time_t型とされている。
C言語の標準である「ISO/IEC 9899:1999」では、time_t型の範囲や精度はいずれも実装定義としているが[1]、伝統的な実装ではこれをintとし、そのintは符号つき32ビットであった。このため最大値は (231 - 1) = 2,147,483,647 となり、取り扱えるのは2,147,483,647秒までに限られていた。
これを前提として作成されたプログラムは、1970年1月1日0時0分0秒から2,147,483,647秒を経過した、2038年1月19日3時14分7秒(閏秒を考慮しない場合)を過ぎると、この値がオーバーフローし、負と扱われる[2]ため、時刻を正しく扱えていることを前提としたコードがあれば、誤作動する。
ある実装における time_t の型を変更することだけであれば、たった1箇所の typedef を書き換えるだけであるが、実際の運用では、アプリケーションプログラムにおける時刻の扱い全てが正しくある必要がある。また、すでにあるデータ構造中で32ビット固定長として割り当てられていれば、問題が発生する。たとえば、Linuxのファイルシステムを例に挙げると、ext2、ext3、ReiserFSのタイムスタンプは同日付までしか対応していない。
この期日以前でもプログラムで内部的にこの制限を超えた時刻データを扱おうとすれば同様のエラーが発生するため、たとえば丁度半分を経過した2004年1月11日にはすでにATMの誤作動といったトラブルが発生した。この事例ではプログラム中のある時刻と別の時刻の中間の時刻を求めるような処理で、相加平均を単純に求める (t1 + t2) / 2 のような式を利用していたものとみられる。他にも顕在化していないトラブルが今後表面化するという可能性はあり得る。
以下のような理由により、2000年問題より深刻であるという指摘もある。
- 2000年問題はアプリケーションレベルでの修正が可能であったが、この問題は現在普及しているC言語処理系やOSのAPIといったシステムの深いレイヤに潜む問題である。
- 「32ビットの符号付二進数の桁あふれ」という理由を理解するには、ある程度の専門知識を必要とするので、一般大衆、経営者、政治家などの理解と関心を得にくい可能性がある。
- 2000年問題のように暦年の変わり目というキリのよいときに地域の標準時に応じて順次に問題の時刻が世界を巡るのではなく、ごく中途半端な時刻に世界同時に一斉に問題の時刻が訪れるので、もし問題が生じた場合は対応するための人的資源の確保がより困難となる可能性がある。
[編集] 対策
対策としては、time_t型を符号つき64ビット整数型(一般にはlong long int型)にするという方法がある。符号つき64ビット整数型の場合、上限は9,223,372,036,854,775,807(263 - 1)である。これを秒数に用いるとおよそ西暦3000億年[3]まで使用できるので、問題が生じることはない。最近のオペレーティングシステムや処理系では、time_t型は符号つき64ビット整数型で表されるようになってきている。
[編集] 関連した問題
- 秒数を2倍して計算すると桁数がオーバーフローしてしまい、負の数として扱われる。一度負の数となると、以後1/2にしても正しく演算を継続できない可能性がある。符号付32ビットの正の最大値の約半分になるのは1,073,741,824秒目であり、2004年1月10日13時37分4秒となる。
- 2001年9月9日問題は、2001年9月9日にtime_t型の値が999,999,999秒から1,000,000,000秒と桁が増えることに伴う問題。time_t型の値を文字列(辞書順)でソートしていたことで、「999,999,999>1,000,000,000」と判断され、項目の新旧が正しく判断されない問題(新しく作られた項目が表示されない、古いものとみなされ削除されるなど)が発生した。
- NTPやMicrosoft Windowsなど、1900年1月1日からの積算秒数で時間を表現するシステムもあり、符号なし32ビットの値が2036年2月6日にオーバーフローすることによって問題が発生する(→2036年問題)。
[編集] 脚注
- ^ "The range and precision of times representable in clock_t and time_t are implementation-defined.", ISO/IEC 9899 7.23.1.4
- ^ 時刻の場合、2038年1月19日3時14分7秒の次は、1901年12月13日20時45分52秒となる。
- ^ 9,223,372,036,854,775,807秒 ÷ (602*24*365.2425) ≒ 2.9228e11年≒3000億年。これは太陽系の寿命よりもはるかに長い(太陽の白色矮星化は西暦70億年ごろ)。
