
前回の
日付表現を便利にするモジュール
(1)
(2)
DateTime ──日付演算を正確に行うモジュール
日付処理の代表的なモジュールとして,DateTime
DateTime
オブジェクトは,new
やfrom_
メソッドなどで時間を直接指定して作成するか,now
メソッドやtoday
メソッドで実行日時から作ることができます。
use DateTime;
my $dt = DateTime->new(
year => 2021,
month => 1,
day => 1,
hour => 0,
minute => 0,
second => 0,
# nanosecond => 0,
time_zone => 'Asia/Tokyo'
);
my $now = DateTime->now(time_zone => 'Asia/Tokyo');
DateTime
オブジェクトは加算や減算の処理が行えますが,Clone
モジュール
use DateTime;
use Clone qw(clone);
my $dt_1 = DateTime->now(time_zone => 'Asia/Tokyo');
my $dt_2 = clone($dt_1);
$dt_2->add(months => 1, days => 1);
演算結果が月末を超える場合の最後の日の合わせ方は,wrap
,limit
,preserve
のいずれかをend_
に指定できます。wrap
は月末を超えて演算します。limit
は月末を超えたら月末に合わせます。preserve
は月末を超えたら月末に合わせたうえで,wrap
で,preserve
です。
$dt->add(months => 1, end_of_month => 'preserve');
また,DateTime
オブジェクトどうしの減算を行う場合,DateTime
オブジェクトのdelta_
メソッドに,DateTime
オブジェクトを渡すことで,DateTime::Duration
DateTime
オブジェクトのin_
メソッドで取り出したい単位を指定します。
use DateTime;
my $dt_1 = DateTime->new( year => 2021, month => 1, day
=> 1, time_zone => 'Asia/Tokyo' );
my $dt_2 = DateTime->new( year => 2021, month => 2, day
=> 1, time_zone => 'Asia/Tokyo' );
my $duration = $dt_2->delta_days($dt_1);
say $duration->in_units('days'); # 差は31日
異なるタイムゾーンのDateTime
オブジェクトどうしの場合は,set_
メソッドで一度UTCに変換してから演算を行い,
$dt_1->set_time_zone('UTC');
DateTime
モジュールは,
しかし,DateTime
モジュールは,
閏秒を考慮しない場合は,Time::Piece
モジュールや次項のTime::Moment
モジュールなどの比較的軽量なモジュールを検討するとよいです。
Time::Moment ──高速な日付演算モジュール
Time::Moment
DateTime
モジュールと似た感覚で扱え,
use Time::Moment;
my $tm = Time::Moment->new(
year => 2021,
month => 1,
day => 1,
hour => 0,
minute => 0,
second => 0,
# nanosecond => 0,
offset => 60 * 9, # 日本時間
);
my $now = Time::Moment->now;
my $utc = Time::Moment->now_utc;
my $epoch = Time::Moment->from_epoch(1000);
Time::Moment
オブジェクトは,DateTime
オブジェクトの破壊的な加算や減算とは異なり,Time::Moment
オブジェクトが作られる非破壊的な処理を行います。また,plus_
や減算するminus_
は,
$tm2 = $tm1->plus_months(1); # 1ヶ月を加算
DateTime
モジュールは実行速度がかなり遅いです。Benchmark
モジュールDateTime
モジュールよりTime::Piece
モジュールが約25倍速く,Time::Moment
モジュールにいたってはDateTime
モジュールより約140倍速いです。頻繁に日付処理を行う場合は,DateTime
モジュールからTime::Moment
モジュールへの移行を検討してもよいでしょう。
use Benchmark qw(cmpthese);
use Time::Moment;
use Time::Piece;
use DateTime;
cmpthese 0, {
'DateTime' => sub {
DateTime->now(time_zone => 'Asia/Tokyo')
},
'Time::Piece' => sub { Time::Piece->localtime },
'Time::Moment' => sub { Time::Moment->now },
};
第66回 モジュールによる時間の多様な取り扱い(2) - Gihyo Jp
Read More
Bagikan Berita Ini
0 Response to "第66回 モジュールによる時間の多様な取り扱い(2) - Gihyo Jp"
Post a Comment