2038年問題とは、時刻を格納する変数のオーバーフローによって引き起こされる事象である。
多くの場合、コンピュータの時刻の起点は1970年1月1日午前0時(協定世界時、つまりUTC)である。これをThe Epochと呼ぶ。一般にCでは時刻は32ビットの符号付整数に格納することにした。
1秒ごとに1ずつ数字が増えるのでうるう秒を考慮しない場合(普通のシステムは考慮しない)、起点時刻から2147483647秒にあたる2038年1月19日午前3時14分7秒(UTC)で時刻がカンストしてしまう。そこから1秒が経過すると、オーバーフローして1901年12月13日20時45分52秒(UTC)になり、当然コンピュータが誤動作する。
時刻参照が現在時刻である必要はないので実装次第ではもっと早い時期から誤動作を引き起こす場合もあり、半分が経過した2004年1月頃にトラブルが頻発していたという(例えば2つの時刻の中間を求める際に「足して2で割る」を行っていれば、足した時点でオーバーフローしてしまうようになる)。
対策は非常に簡単で、32ビットでオーバーフローしないようにしてしまうのが妥当なところである。
64ビットの符号付整数にしたtime_tのカンストは約2922億年後となる。
ただしtime_tの前に別の変数がカンストしてしまう。それがstruct tmのtm_yearである。これは1900年からの年数をintで返す変数なのだが、intは32ビット符号付整数なので、西暦2147485548年にこれが先にオーバーフローしてしまってでたらめな値を返すことになる。
JavaScriptやActionScriptでは、The Epochから1ミリ秒単位で管理する。その上限はうるう秒を考慮せずちょうど1億日である。つまり、275760年9月13日午前0時(UTC)が管理できる上限である。そこから先は無効な日時になってしまう。
Javaの場合、日時はlong型(符号付64ビット)の整数でミリ秒単位で管理する。ということは、それがオーバーフローした瞬間バグを引き起こすわけだが、その時刻は292278994年8月17日午前7時12分55.807秒が上限になり、それより先はオーバーフローして古生代くらいの時刻に戻ってしまう。
この動画はゲームを使って非常にわかりやすく事象を解説してくれている。
掲示板
16 削除しました
削除しました ID: tyltSBHrzB
削除しました
17 ななしのよっしん
2021/05/23(日) 10:35:00 ID: //CDbGqUee
まあ実際、何とかなるだろうさ。
大した問題じゃないって意味じゃなくて、重要な問題だってわかってて解決策もわかってて20年以上前から騒いでる以上、なんとかはなる。
最後の1年くらい、プログラマは死ぬかもしれんが。
改元問題だって、実際不都合表面化したのは「期限1ヶ月とかふざけんな」と騒いでた5月1日じゃなくて、1年以上前からわかってたにもかかわらず騒いでなかったからか忘れてた天皇誕生日の方だったわけだし。
18 ななしのよっしん
2022/11/23(水) 11:11:14 ID: m2lyKTg0yO
例えばFF7Rはアクセス時刻が2038年以上の場合プログラム停止するよう組まれているんだってね
急上昇ワード改
最終更新:2025/12/06(土) 06:00
最終更新:2025/12/06(土) 06:00
ウォッチリストに追加しました!
すでにウォッチリストに
入っています。
追加に失敗しました。
ほめた!
ほめるを取消しました。
ほめるに失敗しました。
ほめるの取消しに失敗しました。