Time::Piece::Over24 - 24時以降の時間をTime::Pieceで扱う

i47_rozary
2011-12-07

前置き

こんにちは。はじめまして i47_rozary と申します。みなさん、意識は高まっていますか? 僕は上々でいたーいです。今回は拙作のTime::Piece::Over24というモジュールを紹介いたします。

皆さん Time::Piece ってモジュールご存知ですか? 軽いとの評判もあり、DateTime に代わって使われるようになってきている時間系のモジュールであります。

ボクは時間周りの処理をよくするので、よく使うんですけれども。Time::Pieceは、24時以降の時間(例えば、25時は翌日の1時であるとか)を扱えないので、深夜帯に生きるボクには活かせづらいときがままありました。
だので、そこら辺をよしなにしたいなといった趣向のモジュールになります。

使い方

24時以降のTime::Pieceオブジェクトを作っちゃう
use strict;
use warnings;
use Time::Piece::Over24;

my $t1 = localtime->from_over24_time("25:00");
print $t1->datetime;
#2011-12-07T01:00:00

my $t2 = localtime->from_over24_datetime("2011-12-01 25:00:00");
print $t2->datetime;
#2011-12-02T01:00:00

時間だけを入れると、当日からの時間を返して、日付までいれるとその日付の通りのTime::Pieceオブジェクトを返してくれます。
簡単ですね。

24時以降の表示をする

こちらは少し面倒です。
切り替わりの時間を指定してあげて使うようにしました。

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

my $t3 = localtime->strptime("2011-01-01 01:00:00","%Y-%m-%d %T");
$t3->over24_offset("03:00:00");
print $t3->over24_datetime;
#2011-12-31T25:00:00

こんな感じで、27時までは前日ですよという様なイメージですね。
この時、over24_datetime上での1日の時間というのは、3時以上27時未満というサイクルで動くようになります。
通常の0時から24時未満を使いたいときは、そのままdatetimeを使えます。

注意事項

この切り替わり時間なんですけれど、現在以下のような感じになっていますのでご注意ください…。

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

my $t4 = localtime->strptime("2011-01-01 01:00:00","%Y-%m-%d %T");
$t4->over24_offset("03:00:00");
print $t4->over24_offset;
#03:00:00

my $t5 = localtime->strptime("2011-01-01 01:00:00","%Y-%m-%d %T");
print $t5->over24_offset;
#03:00:00 同じ!!

だので、切り替わりの時間を別々にしたいときは…。

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

my $t4 = localtime->strptime("2011-01-01 01:00:00","%Y-%m-%d %T");
$t4->over24_offset("03:00:00");
print $t4->over24_offset;
#03:00:00

my $t5 = localtime->strptime("2011-01-01 01:00:00","%Y-%m-%d %T");
print $t5->over24_offset("00:00:00");
print $t5->over24_offset;
#00:00:00

$t4->over24_offset("03:00:00"); #もう一度
print $t4->over24_offset;
#03:00:00

面倒なのですが、このようにして貰えば出来ます。

時の狭間

Aの時間とBの時間の間であるかチェックする機能もつけてみました。
SQLではBETWEENなんですけれど、今回はis_duringとかいうメソッド名にしてしまいました。

use strict;
use warnings;
use Test::MockTime qw/:all/;
use Time::Piece::Over24;

#今が21時だとして
set_absolute_time("2011-12-06T12:00:00Z");

my $t6 = localtime;
print $6->is_during("21:00","25:00");
#1

print $6->is_during("21:10","25:00");
#undef

#datetimeも使えます
print $6->is_during("2011-12-06 21:00:00","2011-12-06 25:00");
#1

#Time::Pieceもそのまま使えます
my $t7 = $6->strptime("2011-12-06 21:00:00","%Y-%m-%d %T");
my $t8 = $6->strptime("2011-12-07 01:00:00","%Y-%m-%d %T");
print $6->is_during($t7,$t8);
#1

1;

という感じで簡単ですよね。
わざわざTime::Pieceに入れ込むなとか言わないであげてください…。

ちなみにTest::MockTimeはTime::Pieceをuseする前にいれてあげてください。

まとめ

Time::Piece好き&&深夜帯大好きが高じてこんなモジュールを作ってみました。
仕様、実装とも不安なところもあるのですが、是非触ってもらえたらと思います。

最後に、Time::PieceTime::Piece::MySQLTest::MockTimeは日頃大変利用させてもらっています。ありがとうございます。