Time::Local で 2038年問題
古いバージョンのTime::Local に、2040年くらいの日付を渡すと死んでしまうみたいです。
たとえば、こんな感じで、1.07(CPAN で取れる一番古いバージョン)と 1.1901(最新)を配置します。
% find . -name Local.pm ./lib/1.07/Time/Local.pm ./lib/1.19/Time/Local.pm
で、こんなプログラムを作ってみます。
#!/usr/bin/perl use strict; use warnings; #use lib qw(lib/1.07); use lib qw(lib/1.19); use Time::Local; print timelocal(00, 00, 00, 01, 0, 2050);# 2050年1月1日
use lib で切り替えて、それぞれのバージョンで動かしてみます。まずは最新。
% perl a.pl 11114510192
大丈夫でした。では 1.07 に切り替えて実行してみます。
% perl a.pl Cannot handle date (0, 0, 0, 1, 0, 2050) at a.pl line 8
うーん、プログラムが die しちゃいます。。。(eval で囲ったり、print の後ろに print を入れると die してるのが分かると思います。)
Time::Local のChangesに
1.19 2008-11-01
- The calculation of the maximum integer size was using
$Config{intsize} when it should use $Config{ivsize}. Apparently on a
64-bit platform intsize can be 4 when ivsize is 8. Based on a patch
from Jan Dubois.
とあるので、1.19 より前はダメっぽい感じです。(ちゃんと検証してませんが)。あとは、コテコテの 32bit 環境だと 1.19 以降を使ってもダメそうですね。(どういう CPU が該当するのかちょっと分かりませんが、少なくとも Core 2 Duoと Pentium D は大丈夫だった。)
現在でも比較的良く使われている(つーか僕も使っていてハマった) Perl 5.8.8 だと、1.11 あたりがバンドルされているっぽいので、注意が必要です。
つーか 2038 年問題なんて、遠い未来のことだと思っていましたが、注意してないとダメなんですねぇ。これからは気をつけよう、っと。
5/30追記
FreeBSD だと 5.10 でもダメでした。。。
% perl -v This is perl, v5.10.0 built for i386-freebsd-thread-multi-64int Copyright 1987-2007, Larry Wall Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5 source kit. Complete documentation for Perl, including FAQ lists, should be found on this system using "man perl" or "perldoc perl". If you have access to the Internet, point your browser at http://www.perl.org/, the Perl Home Page. % perl -MTime::Local -e 'print $Time::Local::VERSION' 1.18 % perl -MTime::Local -e 'print timelocal(00, 00, 00, 01, 0, 2050)' Day too big - 29220 > 24853 Cannot handle date (0, 0, 0, 1, 0, 2050) at -e line 1
cygwin だと大丈夫だったんだけどなぁ。。。ports/devel/p5-Time-Local を入れればアップグレードされます。つーかやっておこう。