2038年問題
[Wikipedia|▼Menu]

この記事は検証可能参考文献や出典が全く示されていないか、不十分です。
出典を追加して記事の信頼性向上にご協力ください。(2015年7月)

2038年問題(にせんさんじゅうはちねんもんだい)は、2038年1月19日3時14分7秒(UTC、以下同様)を過ぎると、コンピュータが誤作動する可能性があるとされる年問題
目次

1 経緯

2 対策

3 関連した問題

4 脚注

5 関連項目

6 外部リンク

経緯 上から、2進・十進・問題のある時刻・正しい時刻。(GIFアニメ)3時14分7秒を超えたところで負の値となり、時刻に狂いが生じる恐れがある。

時刻の表現として「UNIX時間」《協定世界時における1970年1月1日0時0分0秒からの経過秒数[1]》を使用しているコンピュータ等のシステムがある。この起点の時刻は、最初にUNIXにそのような機能が実装された時にキリがよかった過去の時刻であり、たまたまそう決めたというだけのものに過ぎない。

この経過秒数を表現する型は、現在の標準では、「time_t型」である。C言語の標準である「ISO/IEC 9899:1999」では、time_t型の範囲や精度はいずれも実装定義としている[2]。UNIXの標準(POSIX)には「shall be integer or real-floating types.」とのみ記述があり、ビット幅ないし値の範囲については何らの定めも無い。

伝統的な実装ではtime_tをintとし、そのintは符号つき32ビットであった。このため最大値は (231 ? 1) = 2,147,483,647 となり、取り扱えるのは2,147,483,647秒(≒ 68年)までに限られていた。これを前提として作成されたプログラムは、協定世界時における1970年1月1日0時0分0秒(日本標準時では1970年1月1日9時0分0秒)から2,147,483,647秒を経過した、2038年1月19日3時14分7秒(日本標準時では2038年1月19日12時14分7秒、閏秒は考慮していない)を過ぎると、この値がオーバーフローし、と扱われる[3]ため、時刻を正しく扱えていることを前提としたコードがあれば、誤作動する。

ある実装における time_t の型を変更することだけであれば、プログラム中のたった1箇所 (typedef) を書き換えるだけであるが、実際の運用では、アプリケーションプログラムにおける時刻の扱い全てが正しくある必要がある。また、すでにあるデータ構造中で32ビット固定長として割り当てられていれば、問題が発生する。たとえば、Linuxのファイルシステムを例に挙げると、ext2ext3ReiserFSタイムスタンプは同日付までしか対応していない。

この期日以前でもプログラムで内部的にこの制限を超えた時刻データを扱おうとすれば同様のエラーが発生するため、たとえばちょうど半分を経過した2004年1月11日にはすでにATMの誤作動といったトラブルが発生した[4]。この事例ではプログラム中のある時刻と別の時刻の中間の時刻を求めるような処理で、相加平均を単純に求める ( t 1 + t 2 ) / 2 {\displaystyle (t_{1}+t_{2})/2} のような式を利用していたものとみられる(計算機による計算におけるこのような式による、露呈しにくいバグはこの問題に限らず普遍的なものであり、一般に注意を要する)。他にも顕在化していないトラブルが今後表面化するという可能性はあり得る。

以下のような理由により、2000年問題より深刻であるという指摘もある[誰によって?]。

2000年問題はアプリケーションレベルでの修正が可能であったが、この問題は現在普及しているC言語処理系やOSのAPIといったシステムの深いレイヤに潜む問題である。

「32ビットの符号付2進表現におけるラップアラウンド」という理由を理解するには、ある程度の専門知識を必要とするので、一般大衆、経営者、政治家などの理解と関心を得にくい可能性がある。

2000年問題のように暦年の変わり目というキリのよいときに地域の標準時に応じて順次に問題の時刻が世界を巡るのではなく、ごく中途半端な時刻に世界同時に一斉に問題の時刻が訪れるので、もし問題が生じた場合は対応するための人的資源の確保がより困難となる可能性がある。

対策

対策としては、time_t型を符号つき64ビット整数型(一般にはlong long int型)にするという方法がある。符号つき64ビット整数型の場合、上限は9,223,372,036,854,775,807 (263 ? 1) である。これを年数に変換するとおよそ西暦3000億年[5]まで使用できるので、事実上問題が発生することはない。最近のオペレーティングシステム処理系では、time_t型は符号つき64ビット整数型で表されるようになってきている。

また、何らかの事情によりtime_tを64ビット化できない環境に対しては、time_tを符号なし32ビット整数型(一般的にはunsigned long int型)にするという回避策が使われることもある。この場合、上限は4,294,967,295 (232 ? 1) となり、2106年2月7日6時28分15秒(閏秒を考慮しない場合)まで表現可能になる。従って2038年問題は回避できるが、結局2106年には問題が発生するため、あくまで64ビット化が困難な環境に限って適用すべき方法とされる。

macOS(OS X)ではNSDateクラスにて協定世界時の2001年1月1日0時丁度をエポックタイムに更新したため[6][7]、これを使用している限り、2038年については問題を回避できる。
関連した問題

時刻aと時刻bのちょうど中間の時刻を求めたい時、それぞれのUnixタイムをTaとTbとして、(Ta+Tb)/2 のように計算すると、2038年問題の半分以降が経過していればTa+Tbの計算で
オーバーフローし、間違った結果になる。これは1,073,741,824秒目であり、2004年1月10日13時37分4秒以降がこの場合に相当する(実際に2004年1月10日乃至11日に、そのようにして起きたものと思われるトラブルの報告があった[8])。

2001年9月9日問題は、2001年9月9日にtime_t型の値が999,999,999秒から1,000,000,000秒と桁が増えることに伴う問題。time_t型の値を文字列(辞書順)でソートしていたことで、「999,999,999 > 1,000,000,000」と判断され、項目の新旧が正しく判断されない問題(新しく作られた項目が表示されない、古いものとみなされ削除されるなど)が発生した。


次ページ
記事の検索
おまかせリスト
▼オプションを表示
ブックマーク登録
mixiチェック!
Twitterに投稿
オプション/リンク一覧
話題のニュース
列車運行情報
暇つぶしWikipedia

Size:15 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)
担当:FIRTREE