更新履歴
[2015-01-03 14:00] ソーススクリプト修正、Gist アップロード
[2020-01-30 20:00] ソーススクリプト整形
こんばんは。
今日は「2038年問題」についてです。
一般に C 言語では、 UNIX の仕様に基づいて時刻を 1970年01月01日00時00分00秒(UTC(世界標準時))からの経過秒数で表しています。そのうちの多くが、時刻を記録する領域として32ビット(4バイト)の符号付き整数を使用しています。すなわち、二進数で32桁分(10進数で2の32乗)の数が用意されていることになります。
但し、符号付き整数では、二進数の最上位(下位から32桁目)が 0
の場合は正の数、 1
の場合は負の数として扱う。このため、正の数として扱える上限の数は、
1 2 |
|
となる。
つまり、1970年01月01日00時00分00秒 から 21億4748万3647秒 経過した 2038年1月19日3時14分07秒(UTC)、日本時間(JST)では 同12時14分07秒 までの時刻は、正の数として正常に処理することが可能だが、これを1秒でも超えると最上位が 1
の負の数となり、プログラムが誤作動する。
こういうこと。
: | : | : |
2038/01/19 03:14:05 |
01111111 11111111 11111111 11111101 | 2,147,483,645 |
2038/01/19 03:14:06 |
01111111 11111111 11111111 11111110 | 2,147,483,646 |
2038/01/19 03:14:07 |
01111111 11111111 11111111 11111111 | 2,147,483,647 |
2038/01/19 03:14:08 |
10000000 00000000 00000000 00000000 | -2,147,483,648 |
2038/01/19 03:14:09 |
10000000 00000000 00000000 00000001 | -2,147,483,647 |
: | : | : |
勘違いしやすいのは、2038年1月19日3時14分07秒(UTC)を 1
秒越えたときは 0
でも -1
でもなく、 -2,147,483,648
になってしまうということ。
つまり、2038年01月19日03時14分08秒(UTC)は 1970年01月01日00時00分00秒(UTC)から 2,147,483,648
秒 過去ということ。
うちは C 言語で開発してないから関係ない、なんてことは言えない。使っているパソコン自体が殆ど C 言語で作成されたプログラムで動いている。放っておくとほぼ確実に誤動作する。(32ビット環境なら)
パソコンばかりのことでもない。あらゆる電子機器について言えること。
これは2000年問題より深刻な問題だと思う。 早急に(と言っても、17年後までに)64ビットの符号付整数で作り直すなどの対応が必要である。 無論、それまでには時代が変わってあらゆる事が今とは異なっていると思うが・・・
※ちなみに Ruby は 1.9.2 以降は2038年問題に対応しているようだ。
問題の時間までの残り秒数を計算するRubyスクリプト
Rubyで問題の時間までの残り秒数を計算する超簡単なスクリプトを作成してみた。
(2038-01-19 12:14:07 までは正常。2038-01-19 12:14:08 からが問題)
実行すると、
- 問題日時 2038-01-19 12:14:08(JST)の 基準日時 1970-01-01 09:00:00(JST) からの経過秒数(十進数・二進数)
- 現在日時の 基準日時 1970-01-01 09:00:00(JST) からの経過秒数(十進数・二進数)
- 残り秒数(十進数・二進数)
を表示する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
|
以上。