Perl プログラミング - 日付のデータを取り扱う

PROGRAM


日付のデータを取り扱う。

目次

 

日付と時刻

日付と時刻といえば、普通に、"2004/05/10 01:21" というようなものの事を言います。ただし Perl の世界では、 1970/01/01 からの経過秒数で、今がいつであるのかを記憶します。

なぜそうなのかというと…、おそらく…、単純演算を一瞬でこなすパソコンにとってはそのほうが何かと都合がいいからです。人間からしてみれば、1970 年から 10,000 秒後といわれてもさっぱりですけど、パソコンならば瞬時に現在の日付を割り出せます。

そもそも実際には、パソコンからしてみると、今日が何月であろうが何日であろうが、どうでもいいことだったりするのですけどね。パソコンにとって一番肝心なことというと、過去か未来かを人の手を借りずに瞬時に判断できるかどうか、そこが重要ではないかと思います。

 

たとえば年と月と日を別々に記録していたとしましょう。そのとき、過去か未来かを判断するためには面倒な手法が必要になってきます。

年が先であればそれは未来であるのは間違いないですけど、年が一緒であったら月の大小関係を比べ、また月が一緒だったら日の大小関係を比べる…。未来であるかを調べるために、このような手間をかけなくてはいけなくなってしまいます。もっとも、この手間を担うのもプログラマの役割ですので、そっくりそのまま、面倒が自分に帰ってくるのですけどね。

それが、経過秒数として取り扱っていれば、経過秒数が多いほど未来である、これは紛れもない事実。これなら一瞬で新しいものか古いものかを判断することが出来てしまうのでした。他にも、1分後なら 60 を足せばいいわけですし、1時間後なら 3600 を足すという簡単な方法で時刻が進められます。

もっとも、1ヵ月後とかになるとまた厄介です。きっちり1ヶ月進めるためには、現在が何年の何月であるかを把握した上で、では今月は何日まであるか、そのような判断が欠かせません。こういうときには、年月日べつべつで取り扱っている ほうが断然便利となってきます…。

長くなってしまいましたけど、こんな感じで、普段何気なく取り扱っている日付も、パソコンで自由に取り扱うには何かと大変なのでした。

 

現在の日付を取得する

Perl には、現在の時刻を取得する機能が備わっています。

# 1970/01/01 から現在までの経過秒数を取得します。

time

この関数を実行することで、1970 年 01 月 01 日から今までの経過秒数を取得することが出来ます。たとえばこれを print 命令にて使用してみると 1086439313 というような数値が取得できます。これが、そのコンピュータに設定されている現在の時刻です。

ただ、これだけを見てそれが今、何月何日なのかわかる人はまずいないと思います。この辺りを、人間にとってわかりやすい情報に変換する関数もちゃんと用意されています。

# 現在時刻を取得します。

@datetime = localtime(time);

このように、time 関数で取得した経過秒数を localtime 関数に渡してあげることで、現地時間 (日本時間 / JST) で取得することが出来ます。または、国際標準時がほしい場合には localtime ではなく gmtime 関数を使用します。

これらの関数で取得されたデータ @datetime は、次の形で配列として保存されています。

$datetime[0] 現在時刻の秒です。
$datetime[1] 現在時刻の分です。
$datetime[2] 現在時刻の時です。
$datetime[3] 現在時刻の日です。
$datetime[4] 現在時刻の月です。0 から始まる通し番号で返されるので、たとえば1月ならば 0 です。
$datetime[5] 現在時刻の年数です。4 桁のうちの下2桁が返される、とのことですが 2000 年の場合は 100 というように、下 2 桁というよりは、1900 年からの経過年数という感じです。
$datetime[6] 現在時刻の曜日です。日曜日を 0 とした 0 から始まる通し番号で返されます。土曜日は 6 です。
$datetime[7] 01 月 01 日からの経過日数です。

 

これでずいぶんと簡単に、現在時刻を表示することができるようになります。

# 現在時刻を表示します。

@datetime = localtime(time);

 

$year = 1900 + $datetime[5];

$month = $datetime[4] + 1;

$day = $datetime[3];

 

print "$year/$month/$day\n";

たとえば上のような Perl スクリプトを実行すると、次のような結果を得ることができます。

2004/6/5

 

日付データを操作する

表示桁数を整える

日付のデータは数字として取得されます。気にしなければどうでもいいのですけど、たとえば日付を表示したいときに、月と日の表示を 2 桁で統一したい場合もあるかと思います。そのときには printf 関数を使用して調整する必要があります。

# 現在時刻を表示します。

@datetime = localtime(time);

 

$year = 1900 + $datetime[5];

$month = $datetime[4] + 1;

$day = $datetime[3];

 

printf "\%04d/\%02d/\%02d\n", $year, $month, $day;

こうすることで、表示結果は次のようになります。

2004/06/05

 

曜日を文字で表示する

曜日の情報を文字として表示させたい場合は、あらかじめその文字情報を配列として用意します。そして localtime 関数によって取得できる配列の 6 番目の値を使って、該当する曜日文字列を取得します。

# あらかじめ、曜日文字列を用意します。

@week_label = ('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT');

 

# 現在時刻を表示します。

@datetime = localtime(time);

 

$year = 1900 + $datetime[5];

$month = $datetime[4] + 1;

$day = $datetime[3];

$weekname = $week_label[$datetime[6]];

 

printf "\%04d/\%02d/\%02d (%s)\n", $year, $month, $day, $weekname;

このような感じで、曜日番号から曜日を取得することが出来ます。

2004/06/06 (SUN)

 

何分後かを知るのは簡単

時間を取り扱うには何かと気を使う必要がありますけど、経過時間を取得するのは、多くの場合非常に簡単です。

というのも time 関数を使うことで、その時点での 1970 年から蓄積された秒数が取得できるためです。そして少しおいてまた time 関数を呼び出せば、またその時点での経過秒数が取得できる…。

あとは新しい方から古い方を引き算すれば、その 2 つの time を呼び出す間の時間を、経過秒数で取得することが出来ます。何分後かがほしいならばそれを 60 で割ればいいし、何時間後かなら 3600 で割ればいいし、何日後かなら 86400 で割ればいいし。

それ以降になるといろいろと配慮しないといけなくなるでしょうけど、大体はせいぜい "何日" であるかで十分済ませられると思います。世間一般に、一月は 30 日くらい、一年は 365 日くらいというのがおなじみでしょうから、 80 日とか、600 日と言われても、なんとなくは察しがつくとおもいますから。といいますか、 1,000 日とかそこまで長い期間を見越したプログラムと言うのも意外と少ないものでしょう…。

 

以下ではその例として、経過時間を取得して、それを扱いやすくするものを挙げてみます。これで "何日" 経過したかまでを、簡単に表示などができると思います。プログラミング表記に少々癖がありますので注意して眺めてください。

なお引数として、最初に取得した時間 (time 関数) を受け取るものとします。

sub passtime($)

{

# %pass には以下で分割して保存します。

# $time_old には、引数に渡された以前の時間 (time) が格納されます。

 

my %pass;

my $time_old = shift;

 

# 受け取った時刻と現在時刻 (time) から、経過時間を計算しています。

my $passtime = time - $time_old;

 

# 経過総秒数から、秒だけ、分だけ、時だけ、残りをすべて日数で取得します。

$pass{'second'} = $passtime % 60; $passtime = int($passtime / 60);

$pass{'minute'} = $passtime % 60; $passtime = int($passtime / 60);

$pass{'hour'} = $passtime % 24; $passtime = int($passtime / 24);

$pass{'day'} = $passtime;

 

# あとはこの HASH から 'second', 'minute', 'hour', 'day' を参照することで、経過時間を簡単に知ることが出来ます。

return %pass;

}

 


[ もどる ]