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;
こんな感じに書けます。