redhat linux 上のperl5.8.0で下記のようなコードを動かすと
use utf8;
use Date::Simple;
print $Date::Simple::VERSION."\n";
$ENV{'TZ'}= "JST-9";
print "$ENV{'TZ'}\n";
print "1st time is ".localtime()."\n";
my $date = Date::Simple->new();
print "2nd time is ".localtime()."\n";
my $formated_date = $date->format('%Y年%m月%d日') ;
$ENV{'TZ'}= "JST-9";
print "3rd time is ".localtime()."\n";
結果が、
3.02
JST-9
1st time is Mon Apr 5 10:33:13 2010
2nd time is Mon Apr 5 10:33:13 2010
3rd time is Mon Apr 5 01:33:13 2010
な感じで、9時間戻ってしまうのですが、これを回避する方法ありますか?
Date::Simpleは、print $Date::Simple::VERSION."\n"; したところ、3.02 でした。
「 my $formated_date = $date->format('%Y年%m月%d日') ;」
処理以後のタイムゾーンが変更になってしまうので、期間チェックの処理がおかしくなります。
タイムゾーンを再び日本時間JSTに戻すのはどうしたらよいのでしょうか?
use strict; use warnings; use utf8; use Date::Simple; print $Date::Simple::VERSION."\n"; $ENV{'TZ'}= "GMT-9"; # JST print "$ENV{'TZ'}\n"; print "1st time is ".localtime()."\n"; my $date = Date::Simple->new(); print "2nd time is ".localtime()."\n"; $ENV{'TZ'}= "GMT+0"; my $formated_date1 = $date->format('%Y年%m月%d日') ; print "2nd time is ".localtime()."\n"; $ENV{'TZ'}= "GMT-9"; # JST my $formated_date2 = $date->format('%Y年%m月%d日') ; print "3rd time is ".localtime()."\n";
良くわからんが環境変数の設定を勘違いしてるだけでは?
use Time::Local;
だけではNGでした。
すみません。
It does not deal with hours, minutes, seconds, and time zones.
(時分秒とタイムゾーンは扱わない。)
とあるので、ローカルタイムを渡した時の挙動に関して、Date::Simple が最初から意図していないものと思われます。
上記のドキュメントの冒頭も、
Dates are complex enough without times and timezones.
(日付は、時刻やタイムゾーンの話を抜きにしても、十分に複雑だ。)
と言っているので、「タイムゾーンなんて知ったこっちゃない」というところなのかな。
なるほど、根本的に、日付データをフォーマットしたいときの方法が間違ってるんでしょうかね・・・。
コメントありがとうございます。
CentOS 5.4 上の Perl 5.8.8 では、質問にあったスクリプトをそのまま実行しても、9時間ずれる現象は起きません。
実行結果:
-----------------------------------------
3.02
JST-9
1st time is Tue Apr 6 13:36:48 2010
2nd time is Tue Apr 6 13:36:48 2010
3rd time is Tue Apr 6 13:36:48 2010
-----------------------------------------
気になったのは、samasuya が示された、Date::Simple で $ENV{TZ} を書き換えているところですが、本来であれば local で指定されてれば、その行を含むブロックを出た時点で、元の値に戻っているはずです。
しかし、samasuya さんの実行結果だと、Date::Simple が書き換えた後に元に戻らず、かつ、以降、上書き出来なくなっているような雰囲気に見えます。
5.8.0 から 5.8.1 への変更点で、local に関する変更点はあるのですが、
http://fleur.hio.jp/perldoc/perl/5.8.1-RC4/perldelta.ja.html#local____x_
このケースとは違うように思われるので、5.8.0 のバグだ、と決めつける事は出来ません。
う~ん、それとも POSIX の問題なのかなぁ...。
混迷の度を増してしまって、すみません。
意味判る方いらっしゃいますかね?
>意味判る方いらっしゃいますかね?
文面を見る限りでは非常にシンプル。
環境変数 TZ とシステムのタイムゾーンの値は同期しているわけではない。
POSIX::tzset() または同等の関数を呼ぶことで環境変数の値が反映されると言うのが前提になっている。
で、この場合 POSIX::strftime の中で暗黙的に tzset が呼ばれているので strftime 自体は環境変数を反映するが、
そのご、Perl の local 宣言のスコープからはずれ、環境変数が元に戻ってもシステムのタイムゾーンが同時に戻るわけではない。
これを回避するためリンク先では元の環境変数を一時待避、strftime 実行後に環境変数を戻した上で改めて tzset を呼ぶことで
strftime によって変更されたタイムゾーンを元に戻すと言う対処を行っている。
上記はリンク先の内容を説明しただけでその真偽や是非は確認してないけどこんな所。
回答も付かないようなのでこれにて終了いたします。折角なのでコメント頂いた方々にもポイント送信しますね。