「2038年問題」の版間の差分

提供: miniwiki
移動先:案内検索
(1版 をインポートしました)
(内容を「{{テンプレート:20180815sk}} __NOINDEX__」で置換)
(タグ: Replaced)
 
1行目: 1行目:
{{出典の明記|date=2015年7月}}
+
{{テンプレート:20180815sk}} __NOINDEX__
'''2038年問題'''(にせんさんじゅうはちねんもんだい)は、[[2038年]][[1月19日]]3時14分7秒([[協定世界時|UTC]]、以下同様)を過ぎると、[[コンピュータ]]が誤作動する可能性があるとされる[[年問題]]。
 
 
 
== 経緯 ==
 
[[ファイル:Year 2038 problem.gif|right|400px|thumb|上から、2進・十進・問題のある時刻・正しい時刻。([[GIFアニメ]])3時14分7秒を超えたところで負の値となり、時刻に狂いが生じる恐れがある。]]
 
[[時刻]]の表現として「[[UNIX時間]]」《[[協定世界時]]における1970年1月1日0時0分0秒からの経過秒数<ref>「ただし、うるう秒を無視して現在時刻から逆算した値を使用する」として運用されていることが専らである。</ref>》を使用しているコンピュータ等のシステムがある。この起点の時刻は、最初に[[UNIX]]にそのような機能が実装された時にキリがよかった過去の時刻であり、たまたまそう決めたというだけのものに過ぎない。
 
 
 
この経過秒数を表現する型は、現在の標準では、「[[time_t]]型」である。[[C言語]]の標準である「ISO/IEC 9899:1999」では、time_t型の範囲や精度はいずれも実装定義としている<ref>"The range and precision of times representable in clock_t and time_t are implementation-defined.", ISO/IEC 9899 7.23.1.4</ref>。UNIXの標準([[POSIX]])には「shall be integer or real-floating types.」とのみ記述があり、ビット幅ないし値の範囲については何らの定めも無い。
 
 
 
伝統的な実装ではtime_tをintとし、そのintは符号つき[[32ビット]]であった。このため最大値は (2<sup>31</sup> − 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秒、[[閏秒]]は考慮していない)を過ぎると、この値が[[算術オーバーフロー|オーバーフロー]]し、[[負の整数|負]]と扱われる<ref>時刻の場合、2038年1月19日3時14分7秒の次は、'''1901年12月13日20時45分52秒'''となる。</ref>ため、時刻を正しく扱えていることを前提としたコードがあれば、誤作動する。
 
 
 
ある実装における time_t の型を変更することだけであれば、プログラム中のたった1箇所 ([[typedef]]) を書き換えるだけであるが、実際の運用では、アプリケーションプログラムにおける時刻の扱い全てが正しくある必要がある。また、すでにあるデータ構造中で32ビット固定長として割り当てられていれば、問題が発生する。たとえば、Linuxの[[ファイルシステム]]を例に挙げると、[[ext2]]、[[ext3]]、[[ReiserFS]]の[[タイムスタンプ]]は同日付までしか対応していない。
 
 
 
この期日以前でも[[プログラム (コンピュータ)|プログラム]]で内部的にこの制限を超えた時刻データを扱おうとすれば同様のエラーが発生するため、たとえばちょうど半分を経過した2004年1月11日にはすでに[[現金自動預け払い機|ATM]]の誤作動といったトラブルが発生した<ref>大和田尚孝「[http://itpro.nikkeibp.co.jp/free/NC/NEWS/20040202/139212/ コンピュータの“西暦2038年問題”発生、早くも日本を揺るがす]」[[日経コンピュータ]]、2004年2月2日</ref>。この事例ではプログラム中のある時刻と別の時刻の中間の時刻を求めるような処理で、相加[[平均]]を単純に求める <math>(t_1 + t_2) / 2</math> のような式を利用していたものとみられる(計算機による計算におけるこのような式による、露呈しにくいバグはこの問題に限らず普遍的なものであり、一般に注意を要する)。他にも顕在化していないトラブルが今後表面化するという可能性はあり得る。
 
 
 
以下のような理由により、2000年問題より深刻であるという指摘もある{{誰2|date=2015年7月}}。
 
*[[2000年問題]]はアプリケーションレベルでの修正が可能であったが、この問題は現在普及しているC言語処理系やOSのAPIといったシステムの深いレイヤに潜む問題である。
 
*「32ビットの符号付2進表現におけるラップアラウンド」という理由を理解するには、ある程度の専門知識を必要とするので、一般大衆、経営者、政治家などの理解と関心を得にくい可能性がある。
 
*2000年問題のように暦年の変わり目というキリのよいときに地域の標準時に応じて順次に問題の時刻が世界を巡るのではなく、ごく中途半端な時刻に世界同時に一斉に問題の時刻が訪れるので、もし問題が生じた場合は対応するための人的資源の確保がより困難となる可能性がある。
 
 
 
== 対策 ==
 
対策としては、time_t型を符号つき64ビット整数型(一般には'''long long int型''')にするという方法がある。符号つき64ビット整数型の場合、上限は'''9,223,372,036,854,775,807''' (2<sup>63</sup> − 1) である。これを年数に変換するとおよそ西暦3000億年<ref>9,223,372,036,854,775,807秒 ÷ (60<sup>2</sup> × 24 × 365.2425) ≒ 2.9228{{E|11}}年 ≒ 3000億年。これは[[太陽系]]の寿命よりもはるかに長い([[太陽]]の[[白色矮星]]化は西暦68億年ごろ)。</ref>まで使用できるので、事実上問題が発生することはない。最近の[[オペレーティングシステム]]や[[処理系]]では、time_t型は符号つき64ビット整数型で表されるようになってきている。
 
 
 
また、何らかの事情によりtime_tを64ビット化できない環境に対しては、time_tを符号なし32ビット整数型(一般的には'''unsigned long int型''')にするという回避策が使われることもある。この場合、上限は'''4,294,967,295''' (2<sup>32</sup> − 1) となり、[[2106年]]2月7日6時28分15秒(閏秒を考慮しない場合)まで表現可能になる。従って2038年問題は回避できるが、結局2106年には問題が発生するため、あくまで64ビット化が困難な環境に限って適用すべき方法とされる。
 
 
 
[[macOS]](OS X)ではNSDateクラスにて[[協定世界時]]の2001年1月1日0時丁度をエポックタイムに更新したため<ref>[https://developer.apple.com/reference/foundation/nsdate?language=objc NSDate - Foundation | Apple Developer Documentation]</ref><ref>[https://developer.apple.com/library/prerelease/content/documentation/CoreFoundation/Conceptual/CFDatesAndTimes/Concepts/DataReps.html#//apple_ref/doc/uid/20001139-CJBEJBHH Date Representations]</ref>、これを使用している限り、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日に、そのようにして起きたものと思われるトラブルの報告があった<ref>
 
「[http://itpro.nikkeibp.co.jp/members/NC/ITARTICLE/20040325/1// 「西暦2038年問題」でトラブル相次ぐ]」[[日経コンピュータ]]、2004年4月1日</ref>)。
 
*[[2001年9月9日問題]]は、2001年9月9日にtime_t型の値が9億秒から10億秒と桁が増えることに伴う問題。time_t型の値を文字列(辞書順)でソートしていたことで、「9億 > 10億」と判断され、項目の新旧が正しく判断されない問題(新しく作られた項目が表示されない、古いものとみなされ削除されるなど)が発生した。
 
*[[Network Time Protocol|NTP]]など、1900年1月1日からの積算秒数で時間を表現するシステムもあり、符号なし32ビットの値が[[2036年]][[2月7日]]6時28分15秒 (UTC) を超えるとオーバーフローすることによって問題が発生する(→[[Network Time Protocol#2036年問題|2036年問題]])。[[Simple Network Time Protocol|SNTPv4]]を定めたRFC 4330には、最上位ビットが0の場合は時刻が2036年から2104年の間であるとみなして、2036年2月7日6時28分16秒 (UTC) を起点として計算することで2036年問題を回避する方法が書かれている。
 
 
 
== 脚注 ==
 
{{脚注ヘルプ}}
 
{{reflist}}
 
 
 
== 関連項目 ==
 
*[[UNIX時間]]
 
*[[ジョン・タイター]]
 
*[[2000年問題]]
 
 
 
== 外部リンク ==
 
*[http://sunpillar.jf.land.to/bekkan/javascript/2038.shtml#TIMER 2038年問題へのカウントダウン]
 
*[http://support.microsoft.com/kb/436249/JA/ システム日付が2038年以降に設定されていると、Windows XPのセットアップが途中で停止する場合がある]{{Deadlink|date=2018年6月}}
 
 
 
{{年問題}}
 
{{DEFAULTSORT:2038ねんもんたい}}
 
 
 
[[Category:コンピュータ]]
 
[[Category:コンピューター問題]]
 
[[Category:UNIX]]
 
[[Category:コンピュータ史]]
 
[[Category:年問題|2038]]
 
[[Category:情報社会]]
 
[[Category:2038年]]
 

2019/6/7/ (金) 09:49時点における最新版



楽天市場検索: