2038年問題

2038年問題（にせんさんじゅうはちねんもんだい）は、2038年1月19日3時14分7秒（UTC、以下同様）を過ぎると、コンピュータが誤動作する可能性があるとされる年問題。
経緯.
コンピュータおよびコンピュータプログラムにおける時刻の表現として「UNIX時間」《協定世界時における1970年1月1日0時0分0秒からの経過秒数》を採用しているシステムがある。
UNIXおよびUNIX派生のオペレーティングシステム (OS) における基幹ソフトウェア部品の多くはC言語で書かれているが、前述の経過秒数を表現する型は、現在の標準では、「time_t型」である。C言語の標準である「ISO/IEC 9899:1999」では、codice_1型の範囲や精度はいずれも実装定義としている。UNIXの標準 (POSIX) には「shall be integer or real-floating types.」とのみ記述があり、ビット幅および値の範囲については何らの定めも無い。
伝統的な実装ではcodice_1をcodice_3またはcodice_4の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秒、閏秒は考慮していない）を過ぎると、この値がオーバーフローし、もし時刻を正しく扱えていることを前提としたコードがあれば、誤動作する。
ある実装におけるcodice_1の型を変更することだけであれば、プログラム中のたった1箇所 (typedef) を書き換えるだけであるが、実際の運用では、アプリケーションプログラムにおける時刻の扱い全てが正しくある必要がある。また、すでにあるデータ構造中で32ビット固定長として割り当てられていれば、問題が発生する。たとえば、Linuxのファイルシステムであるext2・ext3・ReiserFSのタイムスタンプは同日付までしか対応していない。
この期日以前でもプログラムで内部的にこの制限を超えた時刻データを扱おうとすれば同様のエラーが発生するため、たとえばちょうど半分を経過した2004年1月11日にはすでにATMの誤動作といったトラブルが発生した。この事例ではプログラム中のある時刻と別の時刻の中間の時刻を求めるような処理で、相加平均を単純に求める formula_1 のような式を利用していたものとみられる。他にも顕在化していないトラブルが今後表面化するという可能性はあり得る。
以下のような理由により、2000年問題より深刻であるという指摘もある<ref name="change-makers.jp/technology/11351"></ref>。
対策.
対策としては、codice_1型を符号付き64ビット整数型（一般にはcodice_7型）にするという方法がある。符号付き64ビット整数型の場合、上限は（ − 1）である。これを年数に変換するとおよそ西暦3000億年まで使用できるので、事実上問題が発生することはない。64ビット版のオペレーティングシステムや処理系では、codice_1型は符号付き64ビット整数型で表されるようになってきている。UNIXベースのOSでは、64ビット版でcodice_1も併せて64ビット化されることが多い。
何らかの事情によりcodice_1を64ビット化できない環境に対しては、codice_1を符号無し32ビット整数型（一般的にはcodice_12型）にするという回避策が使われることもある。この場合、上限は（ − 1）となり、2106年2月7日6時28分15秒（閏秒を考慮しない場合）まで表現可能になる。従って2038年問題は回避できるが、結局2106年には問題が発生するため、あくまで64ビット化が困難な環境に限って適用すべき方法とされる。
macOS (Mac OS X 10.0) ではcodice_13クラスにて協定世界時の2001年1月1日0時ちょうどをエポックタイムとして刷新し、また経過時間の内部表現として倍精度浮動小数点数を用いるようになったため、これらを使用している限り、2038年については問題を回避できる。なお、macOS Mojaveは32ビットアプリケーションを動作させることのできる最後のバージョンとなり、macOS Catalinaでは起動することができなくなった。
32ビット版のMicrosoft Windows (Win32) では内部時刻の表現に64ビット化されたcodice_14構造体を使っており、codice_1を使っているわけではない。そのため、Windows OS側に関しては、旧OSに関する一部のケースを除き、32ビット版であっても2038年問題は発生しない。ただし、Microsoft C/C++ (MS-C) および古いバージョンのMicrosoft Visual C++ (MSVC) においては、codice_1は32ビットのcodice_17を使って定義されていたため、これらの古い処理系のC/C++ランタイムライブラリ (CRT) を利用して構築されたアプリケーションソフトウェアやDLLなどは、2038年問題を抱えていることになる。x64アーキテクチャの64ビット版Windows OS上ではWOW64サブシステムによりx86アーキテクチャ向けに構築された32ビットアプリケーションも動作させることができるが、古い32ビットアプリケーションにおける2038年問題は、たとえWindows OSを64ビット版に入れ替えたとしても回避することはできない。Microsoft Visual C++ 2005以降では、既定でcodice_1はcodice_19と等しく、32ビットアプリケーションであってもcodice_1は64ビット化されるため、古いアプリケーションを新しい処理系およびランタイムで構築し直せば2038年問題を回避できる。