C言語の時刻取得の勉強として、以下のようなプログラムを作成する。
#include <time.h> #include <stdio.h> int main() { time_t test; time(&test); printf("今年は:%ld\n", (1970 + test/3600/24/365)); test += 20*365*24*3600; printf("20年後は:%ld\n", (1970 + test/3600/24/365)); test += 1*365*24*3600; printf("21年後は:%ld\n", (1970 + test/3600/24/365)); return 0; }
time_t型には秒が入っているので、年に変換して表示している。(誤差はとりあえず無視)
では、この結果はどのようになるだろうか?
今年は:2017
20年後は:2037
21年後は:1903
※32bit GCCでビルド。
この原因は、PCの時刻の表現が、基準日時を1970/01/01 00:00:00(UTC)として、そこからの経過時間をtime_t型の値としているため。
time_t型のビット長は実装依存だが、多くの環境で使用されている符号付き32ビットの場合、2038/01/19 03:14:07(UTC ※日本時間では12:14:07)でオーバーフローする。
現在はtime_t型を符号付き64ビットにするなどコンパイラ側で対応されているので、最近のコンパイラでビルドをしたプログラムなら問題ないはず。
しかし、再ビルドせずに使い続けられているモジュールは多い。
また、旧システムの改修には古いコンパイラを使用することもある。
ソースコードもあらかじめ決められた要件の箇所以外は触ることはなく、だれにも気づかれずに残り続ける可能性がある。
新旧さまざまなシステムのどこに32ビットのtime_tが使われているかわからない。
これからも気にし続ける必要がある。