2038年問題とは? わかりやすく解説

にせんさんじゅうはちねん‐もんだい〔ニセンサンジフハチネン‐〕【二〇三八年問題】


2038年問題

企業活動のほかの用語一覧
コンピュータシステム:  1Uサーバー  2000年問題  2036年問題  2038年問題  5250  TSS  TCO

2038年問題

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2025/08/07 09:03 UTC 版)

2038年問題(にせんさんじゅうはちねんもんだい)は、協定世界時(UTC)2038年1月19日3時14分7秒(日本標準時の場合、1月19日12時14分7秒)を過ぎると、コンピュータが誤動作する可能性があるとされる年問題

経緯

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

コンピュータおよびコンピュータプログラムにおける時刻の表現として「UNIX時間」(協定世界時における1970年1月1日0時0分0秒からの経過秒数[注釈 1])を採用しているシステムがある。

UNIXおよびUNIX派生のオペレーティングシステム(OS)における基幹ソフトウェア部品の多くはC言語で書かれているが、前述の経過秒数を表現する型は、現在の標準では、「time_t型」である。C言語の標準である「ISO/IEC 9899:1999」では、time_t型の範囲や精度はいずれも実装定義としている[1]。UNIXの標準(POSIX)には「shall be integer or real-floating types.」とのみ記述があり、ビット幅および値の範囲については何らの定めも無い。

伝統的な実装ではtime_tintまたはlongtypedefによる型エイリアス(別名)とし、その型は符号付き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秒、閏秒は考慮していない)を過ぎると、この値がオーバーフロー[注釈 2]、もし時刻を正しく扱えていることを前提としたコードがあれば、誤動作する。

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

この期日以前でもプログラムで内部的にこの制限を超えた時刻データを扱おうとすれば同様のエラーが発生するため、たとえばちょうど半分を経過した2004年1月11日にはすでにATMの誤動作といったトラブルが発生した[2]。この事例ではプログラム中のある時刻と別の時刻の中間の時刻を求めるような処理で、相加平均を単純に求める のような式を利用していたものとみられる[注釈 3]。他にも顕在化していないトラブルが今後表面化するという可能性はあり得る。

2000年問題はアプリケーションレベルでの修正が可能であったが、この問題は現在普及しているC言語処理系やOSのAPIといったシステムの深い層に潜む問題であるため、2000年問題より深刻であるという指摘もある[3]

対策

対策としては、time_t型を符号付き64ビット整数型(一般にはlong long int)にするという方法がある。符号付き64ビット整数型の場合、上限は9,223,372,036,854,775,807(263 − 1)である。これを年数に変換するとおよそ西暦3000億年[注釈 4]まで使用できるので、事実上問題が発生することは遠く後になる。64ビット版のオペレーティングシステム処理系では、time_t型は符号付き64ビット整数型で表されるようになってきている。UNIXベースのOSでは、64ビット版で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ビット化が困難な環境に限って適用すべき方法とされる。

macOSMac OS X 10.0)ではNSDateクラスにて協定世界時の2001年1月1日0時ちょうどをエポックタイムとして刷新し[4][5]、また経過時間の内部表現として倍精度浮動小数点数を用いるようになったため[6]、これらを使用している限り、2038年については問題を回避できる。なお、macOS Mojaveは32ビットアプリケーションを動作させることのできる最後のバージョンとなり、macOS Catalinaでは起動することができなくなった[7]

32ビット版のMicrosoft Windows(Win32)では内部時刻の表現に64ビット化されたFILETIME構造体[8]を使っており、time_tを使っているわけではない。そのため、Windows OS側に関しては、旧OSに関する一部のケースを除き[9]、32ビット版であっても2038年問題は発生しない[10]。ただし、Microsoft C/C++(MS-C)および古いバージョンのMicrosoft Visual C++(MSVC)においては、time_tは32ビットのlong intを使って定義されていたため、これらの古い処理系のC/C++ランタイムライブラリ(CRT)を利用して構築されたアプリケーションソフトウェアDLLなどは、2038年問題を抱えていることになる。x64アーキテクチャの64ビット版Windows OS上ではWOW64サブシステムによりx86アーキテクチャ向けに構築された32ビットアプリケーションも動作させることができるが、古い32ビットアプリケーションにおける2038年問題は、たとえWindows OSを64ビット版に入れ替えたとしても回避することはできない。Microsoft Visual C++ 2005以降では、既定でtime_t__time64_tと等しく[11]、32ビットアプリケーションであってもtime_tは64ビット化されるため、古いアプリケーションを新しい処理系およびランタイムで構築し直せば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日に、この事例と推察される報告があった[12]。 この問題を回避するためには、計算方法を工夫する必要がある。例えば、時刻の中間を求める際に、オーバーフローを避けるために次のような方法が考えられる:
    1. 時刻の差を計算する: まず、時刻bから時刻aを引いて、その差を求める。
    2. 差の半分を求める: 求めた差を2で割る。
    3. 時刻aに加える: 最後に、時刻aに差の半分を加えることで、中間の時刻を求める。 この方法を数式で表すと、次のようになる: 中間時刻=Ta +TbTa)/ 2

類似する年問題

  • 2001年9月9日問題は、2001年9月9日にtime_t型の値が9億秒から10億秒と桁が増えることに伴う問題。time_t型の値を文字列(辞書順)でソートしていたことで、「9億 > 10億」と判断され、項目の新旧が正しく判断されず、新しく作られた項目が表示されない、古いものとみなされ削除されるなどの問題が発生した。
  • NTPなど、1900年1月1日からの積算秒数で時間を表現するシステムもあり、符号なし32ビットの値が2036年2月7日6時28分15秒 (UTC) を超えるとオーバーフローすることによって問題が発生する(→2036年問題)。SNTPv4を定めたRFC 4330には、最上位ビットが0の場合は時刻が2036年から2104年の間であるとみなして、2036年2月7日6時28分16秒(UTC)を起点として計算することで2036年問題を回避する方法が書かれている。
  • 2038年4月23日問題 - ユリウス通日を内部日付表現に用いる物のうち、基準日(グレゴリオ暦1858年11月17日正午)からの修正ユリウス日(MJD)を使用し、かつ16ビットで処理しているシステムでは、日数が16ビットからあふれるために問題が起こる。

脚注

注釈

  1. ^ 「ただし、うるう秒を無視して現在時刻から逆算した値を使用する」として運用されていることが専らである。
  2. ^ Cではオーバーフロー発生時の動作は未定義。整数が2の補数でオーバーフローした値がと扱われる場合、2038年1月19日3時14分7秒の次は1901年12月13日20時45分52秒となる。
  3. ^ 計算機による計算においては、このような一見して何の変哲もない式によるバグは入力数値がある程度大きくならないと露呈しにくく、この問題に限らず普遍的なものであり、一般に注意を要する。
  4. ^ 9,223,372,036,854,775,807 秒 ÷ (602 × 24 × 365.2425) ≒ 2.9228×1011年 ≒ 3000億年。これは太陽系の寿命よりもはるかに長い(太陽白色矮星化は西暦68億年ごろ)。

出典

関連項目

外部リンク


2038年問題

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/02/13 01:55 UTC 版)

UNIX」の記事における「2038年問題」の解説

詳細は「2038年問題」を参照 Unixでは、システム時刻の値を1970年1月1日午前0時0分0秒からの秒数で表しており、これをUNIX時間と呼ぶ。この値のデータ型time_t で、歴史的に符号つき long」と定義されている。32ビットシステムでは、2038年1月19日にこの値が1個の0に31個の1が続く最大値 (0x7FFFFFFF) となり、1秒後には1個の1と31個の0が続く値 (0x80000000) となる。するとシステム時刻は、実装によって(符号ビット無視するか否かによって)1901年または1970年リセットされる。 1970年より前の時刻UNIX時間で表すことは滅多にないため、time_t符号なし32ビット整数定義し直すという対策考えられる。しかし、それでは単に問題2106年2月7日遅延させるだけであり、時刻の差を計算するソフトウェアバグ生じ可能性がある。 この問題対処しているバージョンもある。例えば、SolarisLinux64ビット版では、time_t64ビットとなっており、OS自身64ビットアプリケーション群も約2920億年間正しく動作する64ビット版Solaris既存32ビットアプリケーション動作させることもできるが、その場合は問題残ったまである一部ベンダー標準time_tそのままにして、64ビット代替データ型とそれを使用するAPI別途用意している。NetBSDでは、次のメジャーバージョンである 6.x で32ビット版でも time_t64ビット拡張することを決定した従来32ビットtime_t使用しているアプリケーションは、バイナリ互換レイヤー作って対応する

※この「2038年問題」の解説は、「UNIX」の解説の一部です。
「2038年問題」を含む「UNIX」の記事については、「UNIX」の概要を参照ください。

ウィキペディア小見出し辞書の「2038年問題」の項目はプログラムで機械的に意味や本文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。 お問い合わせ



固有名詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「2038年問題」の関連用語

2038年問題のお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



2038年問題のページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
デジタル大辞泉デジタル大辞泉
(C)Shogakukan Inc.
株式会社 小学館
IT用語辞典バイナリIT用語辞典バイナリ
Copyright © 2005-2025 Weblio 辞書 IT用語辞典バイナリさくいん。 この記事は、IT用語辞典バイナリの【2038年問題】の記事を利用しております。
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアの2038年問題 (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。
ウィキペディアウィキペディア
Text is available under GNU Free Documentation License (GFDL).
Weblio辞書に掲載されている「ウィキペディア小見出し辞書」の記事は、WikipediaのUNIX (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。

©2025 GRAS Group, Inc.RSS