Perlで日時のタイムゾーンを変更する
前回はPHPでの日時情報のタイムゾーン操作を取り上げましたが、今度はPerlで同じことをしてみます。
Perlでの日時操作は5.10からコアに組み込まれたTime::Pieceを利用するケースが一般的ですが、タイムゾーン操作を伴う場合はDateTimeとDateTime::TimeZoneを利用します。
use strict; use warnings; use utf8; use DateTime; use DateTime::TimeZone; my $tz = DateTime::TimeZone->new('name' => 'local'); my $dt = DateTime->now('time_zone' => $tz); print $dt->datetime, "\n"; # YYYY-MM-DD HH:mm:ssで表示 print $dt->strftime('%G-%m-%dT%T%z'), "\n"; # タイムゾーンを表示に含める場合 # UTCへ変換 $dt->set_time_zone('UTC'); print $dt->datetime, "\n"; # ロンドンのタイムゾーンへ変換 $dt->set_time_zone('Europe/London'); print $dt->datetime, "\n"; # N.Y.のタイムゾーンへ変換 $dt->set_time_zone('America/New_York'); print $dt->datetime, "\n"; 1;
もちろんサマータイムは考慮してくれます。
前のサンプルのように前もってDateTime::TimeZoneオブジェクトを作成して、DateTimeのコンストラクトの際に引数としてDateTime::TimeZoneオブジェクトを渡してやる方が処理が早いのですが、単純に任意のタイムゾーンの現在時刻を表示させるなら
print DateTime->now('time_zone' => 'Europe/Paris')->datetime;
という書き方もできます。
PerlのDateTimeの場合も当然のように、現在日時でなくてもオブジェクトが作成できます。DateTimeでオブジェクトを作成する場合、
use strict; use warnings; use utf8; use DateTime; $dt = DateTime->new( time_zone => 'Asia/Tokyo', year => 2011, month => 9, day => 15, hour => 9, minute => 0, second => 0 ); print $dt->datetime, "\n"; 1;
としますが、インターネット上でよく使われる日時記述からDateTimeオブジェクトを作成する場合はDateTime::Format::HTTPを利用して、
use strict; use warnings; use utf8; use DateTime::Format::HTTP; my $dt = DateTime::Format::HTTP->parse_datetime('2011-09-15T09:00:00Z'); print $dt->set_time_zone('Asia/Tokyo')->datetime, "\n"; 1;
と書くと、いちいち日付情報を分割せずに済むので便利です。
特定の用途のために任意の書式で出力したい場合、strftimeメソッドでちまちま指定すれば目的が適いますが、よく使いそうな書式はCPANで公開されてることがよくあります。
例えばメールヘッダー用。
use strict; use warnings; use utf8; use DateTime::Format::HTTP; use DateTime::Format::Mail; my $dt = DateTime->now('time_zone' => 'Asia/Tokyo'); my $mail_format = 'DateTime::Format::Mail'; print $mail_format->format_datetime, "\n"; 1;
こんな感じに書けます。