読者です 読者をやめる 読者になる 読者になる

tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

Time::Pieceで時間比較したときの9時間ずれ問題メモ

ちょっとperlやってないと毎回忘れるのでメモ

やりたいこと

やりたいことは単純で、

○○年○○月○○日○○時過ぎたらこの処理やる
時間の比較にはTime::Pieceを使う

みたいなことですけど、毎回同じトコで間違って調べては対応って繰り返してるので
メモって自分をいましめようと思った次第です。。orz

さっそく

毎回間違うソース

timepice_test.pl

#!/usr/bin/perl

use strict;
use warnings;
use Time::Piece;

my $tp_now          = localtime;
my $target_datetime = '2013-12-12 19:22:00';
my $tp_target       = Time::Piece->strptime($target_datetime, '%Y-%m-%d %H:%M:%S');

warn "now datetime    :" .$tp_now->datetime;
warn "target datetime :" .$tp_target->datetime;
warn "\n";

warn "now timezone    :" .$tp_now->strftime('%Z');
warn "target timezone :" .$tp_target->strftime('%Z');
warn "\n";

warn "now epoch       :" .$tp_now->epoch;
warn "target epoch    :" .$tp_target->epoch;
warn "\n";

if( $tp_now > $tp_target )
{
        warn "hogehoge";
}
else
{
        warn "piyopiyo";
}
毎回間違う結果

今の時間が2013-12-12 19:23:00分だったとすると、期待する結果としては最後に'hogehoge'が出て欲しいです。
が、結果はこうなります

# perl timepice_test.pl
now datetime    :2013-12-12T19:22:47 at timepice_test.pl line 12.
target datetime :2013-12-12T19:22:00 at timepice_test.pl line 13.

now timezone    :JST at timepice_test.pl line 16.
target timezone :JST at timepice_test.pl line 17.

now epoch       :1386843767 at timepice_test.pl line 20.
target epoch    :1386876120 at timepice_test.pl line 21.

piyopiyo at timepice_test.pl line 30.

datetimeの値はnow > targetで、タイムゾーンも'JST'ですが
epochの値はnow < targetで最終結果も'piyopiyo'となってしまいます

正しい対応

正しいソース

原因の詳細は、自分が毎回見る他の方が書いてくれてる記事にあるので割愛しますが
対応方法はTime::Piece->strptimeをさらにlocaltimeでかこってやればOKです

my $tp_target       = Time::Piece->strptime($target_datetime, '%Y-%m-%d %H:%M:%S');
↓
my $tp_target       = localtime(Time::Piece->strptime($target_datetime, '%Y-%m-%d %H:%M:%S'));

ちなみにいつも参考にさせて頂いてるのはこちら
Time::Piece とタイムゾーンの甘い罠

正しい結果
# perl timepice_test.pl
now datetime    :2013-12-12T19:28:51 at timepice_test.pl line 12.
target datetime :2013-12-12T19:22:00 at timepice_test.pl line 13.

now timezone    :JST at timepice_test.pl line 16.
target timezone :JST at timepice_test.pl line 17.

now epoch       :1386844131 at timepice_test.pl line 20.
target epoch    :1386843720 at timepice_test.pl line 21.

hogehoge at timepice_test.pl line 26.

補足

いつも参考にさせて頂いてる記事にも記載がありますが、
Time::Pieceのバージョンが1.15以下(含む)だとlocaltimeでかこってもダメ
みたいですので気をつけましょう

自分が最初に試した環境も'1.14'でうまくいきませんでしたw

# vi /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/Time/Piece.pm
---- 省略 ----
our $VERSION = '1.14';
--------------