にせんさんじゅうはちねん‐もんだい〔ニセンサンジフハチネン‐〕【二〇三八年問題】
2038年問題
別名:西暦2038年問題,コンピュータの2038年問題,コンピュータの西暦2038年問題
【英】the year 2038 problem
2038年問題とは、UNIX環境で運用されているシステムにおいて、西暦2038年1月に時間計測の値がオーバーフローを起こして誤作動する可能性があるという問題のことである。
UNIXの環境は1970年1月1日0時0分0秒を時刻計算の起点としており、32ビットの符号付き整数で経過秒数を計測することによって時刻を計算している。こうした環境では累計で2の31乗秒、およそ21億秒を超えると、数値が正しく扱えなくなって誤作動を起こす可能性がある。1970年1月1日から累計21億秒後を迎えるのが、西暦2038年1月19日にであるとされている。
2004年に、KDDIが国内通話サービスにおいて通話料金が一部過剰に請求されていたことが判明したが、その原因は2038年問題によるものであると発表されている。問題が発生したシステムは0.5秒単位で時刻を計測するシステムで、2004年1月は1970年から2038年までの期間のちょうど半分にあたっていた。
2038年問題
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2025/03/10 04:15 UTC 版)
![]() | この記事は検証可能な参考文献や出典が全く示されていないか、不十分です。(2015年7月) |
2038年問題(にせんさんじゅうはちねんもんだい)は、協定世界時(UTC)2038年1月19日3時14分7秒(日本標準時の場合、1月19日12時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_t
をint
またはlong
のtypedefによる型エイリアス(別名)とし、その型は符号付き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のファイルシステムであるext2・ext3・ReiserFSのタイムスタンプは同日付までしか対応していない。
この期日以前でもプログラムで内部的にこの制限を超えた時刻データを扱おうとすれば同様のエラーが発生するため、たとえばちょうど半分を経過した2004年1月11日にはすでにATMの誤動作といったトラブルが発生した[2]。この事例ではプログラム中のある時刻と別の時刻の中間の時刻を求めるような処理で、相加平均を単純に求める
2038年問題
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/02/13 01:55 UTC 版)
詳細は「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日に遅延させるだけであり、時刻の差を計算するソフトウェアでバグを生じる可能性がある。 この問題に対処しているバージョンもある。例えば、SolarisやLinuxの64ビット版では、time_t は64ビットとなっており、OS自身も64ビットのアプリケーション群も約2920億年間正しく動作する。64ビット版Solarisで既存の32ビットアプリケーションを動作させることもできるが、その場合は問題が残ったままである。一部ベンダーは標準の time_t はそのままにして、64ビットの代替データ型とそれを使用するAPIを別途用意している。NetBSDでは、次のメジャーバージョンである 6.x で32ビット版でも time_t を64ビットに拡張することを決定した。従来の32ビットの time_t を使用しているアプリケーションは、バイナリ互換性レイヤーを作って対応する。
※この「2038年問題」の解説は、「UNIX」の解説の一部です。
「2038年問題」を含む「UNIX」の記事については、「UNIX」の概要を参照ください。
- 2038年問題のページへのリンク