Movable Typeでの2038年問題

mixiのMovable Typeのコミュニティに、以下のような質問が上がっていました。

『エラーが発生しました。Cannot handle date (04, 40, 12, 16, 5, 2099) 』 というエラーメッセージが表示されるが、問題の原因を検索してみても分からなかった。

この件について調べてみると、「2038年問題」による影響であることが分かりました。

2038年問題

多くのシステムでは、日付/時刻の情報を、「1970年1月1日0時0分0秒からの経過秒数」で表しています。
今のところは、この方式で特に問題はありません。

ところが、この方式で、経過秒数を「符号付き32ビット整数」で扱っているシステムもあります。
符号付き32ビット整数では、表せる数の上限は、2,147,483,647(=2の31乗から1を引いた値)です。
1970年1月1日0時0分0秒から2,147,483,647秒経過した日時は、2038年1月19日3時14分7秒です。
そのため、経過秒数を符号付き32ビット整数で表しているシステムでは、上記の日時より後の日時を正しく表すことができず、それ以後のシステムの動作に問題が生じると考えられます。
これを「2038年問題」と呼びます。

PerlのTime::Localモジュールの2038年問題

Perlで日時を処理するモジュールの1つに、「Time::Local」があります。
Time::Localはよく使われているモジュールで、年/月/日/時/分/秒から、1970年1月1日以降の経過秒数を求める時に使います。
ただ、Time::Localモジュールの古いバージョンには、2038年問題が含まれています。
そのため、2038年問題に引っかかる日時を処理しようとすると、「Cannot handle date (秒, 分, 時, 日, 月, 年)」のようなエラーメッセージが表示されます。

Movable Typeでも、内部的にTime::Localモジュールを使っている箇所があります。
そのため、Time::Localモジュールのバージョンが古いと、2038年問題が起こり、冒頭に挙げたようなエラーが発生します。

Time::Localモジュールでの2038年問題の解決

Time::Localモジュールでの2038年問題は、現在の最新バージョンでは解決されています。
したがって、Time::Localモジュールをバージョンアップすれば、Movable TypeでもTime::Localモジュールでの2038年問題を解決することができます。

基本的には、サーバーにインストールされているTime::Localモジュールをバージョンアップすることが望ましいです。
占有サーバーなど、自分でモジュールをインストールできるサーバーなら、cpanコマンドでTime::Localモジュールをバージョンアップします。
一方、共有サーバー等で、自分ではモジュールをインストールできない場合は、サーバーの業者にTime::Localモジュールのバージョンアップを依頼します。

また、Movable Typeだけとりあえず対処するには、以下の手順を取ります。

  • Movable Typeのインストール先の「extlib」ディレクトリの中に、「Time」ディレクトリを作ります。
  • http://cpansearch.perl.org/src/DROLSKY/Time-Local-1.1901/lib/Time/Local.pm」に接続し、Time::Localモジュールの最新版のソースコードを表示します。
  • ソースコードを全てコピーし、テキストエディタに貼り付けて、「Local.pm」というファイル名で保存します。
  • 先ほど作った「Time」ディレクトリの中に、今保存した「Local.pm」ファイルをアップロードします。

ただし、サーバーのOSの種類や、インストールされているライブラリによっては、Time::Localモジュールをバージョンアップするだけでは、問題が解決しないこともあります。