C言語と2038年問題

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が使われているかわからない。

これからも気にし続ける必要がある。