めでたく人類かマヤ暦が終了したところで、本当の人類滅亡について考察してみました。

人類ではなくて、電脳ですが、人類が滅亡する頃には電脳なしに人類がやっていけるとは思えないので。

GEEK以外の方のために解説すると、これ、いわゆる2038年問題です。

2038年問題 - Wikipedia
2038年問題(にせんさんじゅうはちねんもんだい)は、2038年1月19日3時14分7秒(UTC、以下同様)を過ぎると、コンピュータが誤動作する可能性があるとされる年問題。

で、*nixな電脳で時刻を格納している型がtime_tなのですが、これが32bitの符号付き整数の最大値のままだと、1970年01月01日00:00:00 UTCから0x7fffFFFF秒後までしか記録できないので歴史オワタとなるというわけ。Gene Mapperにもネタとして出てきますが、2038年を待たずしてすでに先手が打たれていたので感心したわけです。

すでに対策されている代表格が、JavaScript。JavaScriptのDate型は秒ではなくミリ秒で時刻を扱うので、32bitの壁なんか生まれた時から破れてるわけです。ただし数値は64bit整数ではなく浮動小数点なので、こんな感じ。


まあこの先1万年以上大丈夫なのですが、45億年にはだいぶ足りません。

加えてtime_tが64bitになっているのは、今のところ64bitなOSに限られているようです。

  • OS X Mountain Lion @ HFS+
  • FreeBSD/amd64 8.3-RELEASE @ UFS2 & ZFS
  • Ubuntu 12.10/x86_64 @ EXT4

では

% touch -t 414708201632.15 future
% ls -l future 
-rw-rw-r-- 1 dankogai dankogai 0 Aug 20  4147 future

となるのですが、

  • FreeBSD/i386 7-Stable @ UFS2
  • Ubuntu 12.10/i686 @ EXT4

では

% touch -t 414708201632.15 future
touch: out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]

となってしまいます。

加えて残念なことに、ファイルの日付をあまり未来に設定すると、ファイルのメタデータそのものはOKでも表示系が狂ってしまうようです。例えば

% touch eow
% perl -lE 'my $when=0x7fff_ffff_ffff_ffff; say utime $when, $when,shift' eow
1

というように一見何の問題なく日付を設定しても、OS X Mountain Lionでは

% ls -l eow
Segmentation fault

となってしまいますし、FreeBSD/amd64 でも

$ ls -l eow 
-rw-r--r--  1 dankogai  dankogai  0 Jan  0  1900 eow

という具合です。

こうなるとどこまで未来に行けるのか気になってきます。以下のPerl Scriptでチェックしてみました。

use 5.012;
my $head = 0x0000_0000_0000_0000;
my $tail = 0x7fff_ffff_ffff_ffff;
my ($when, $next);
while ($next = $head + $tail >> 1) {
    last if $when == $next;
    $when = $next;
    # warn "$head, $when, $tail";
    !!(gmtime $when) ? $head = $when + 1 : $tail = $when - 1;
}
say $when;
say scalar gmtime $when;
say scalar localtime $when;
say scalar gmtime $when+1;

ずいぶんへんてこな数字が出てきましたが、西暦2,147,483,647年は0x7fffFFFFなので、どうやら時刻を文字列に変換するgimtime()/localtime()の方に32bit問題が残っているようです。なぜ12月31日ではなく12月29日なのかも謎です。

それでもここまでの日付は、OS X Mountain Lion と FreeBSD/amd64 でタイムスタンプ押せました。

% perl -lE 'my $when=67767976233316804; say utime $when, $when,shift' eow
1
% ls -l eow
-rw-r--r--  1 dankogai  staff  0 Dec 29  2147483647 eow

西暦2,147,483,647年12月29日期限のティケットを今から切っておきましょう>関係者各位

Dan the Mortal