tsucchi’s diary(元はてなダイアリー)


Time::Local で 2038年問題

古いバージョンのTime::Local に、2040年くらいの日付を渡すと死んでしまうみたいです。

たとえば、こんな感じで、1.07(CPAN で取れる一番古いバージョン)と 1.1901(最新)を配置します。

% find . -name Local.pm


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

大丈夫でした。では 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 DuoPentium D は大丈夫だった。)

現在でも比較的良く使われている(つーか僕も使っていてハマった) Perl 5.8.8 だと、1.11 あたりがバンドルされているっぽいので、注意が必要です。

つーか 2038 年問題なんて、遠い未来のことだと思っていましたが、注意してないとダメなんですねぇ。これからは気をつけよう、っと。


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'
% 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 を入れればアップグレードされます。つーかやっておこう。