今年の残り日数
今年は残り何日でしょうか?
本日(指定した日)から年の末日(12月31日)までの日数を調べる Perl/CGIプログラムを作成 してみましょう。
前回は、 元日からの経過日数を算出するPerl/CGIプログラムを作成 しました。
今回はその逆ですね。
Perl/CGIプログラム作成
年の末日(12月31日)まで残り何日なのかを調べる Perl/CGIプログラムを作成 してみましょう。
#!/usr/bin/perl
use strict;
my($day, $month, $year) = (localtime(time))[3..5];
$year += 1900;
$month += 1;
print "Content-type: text/html; charset=shift_jis\n\n";
print '今日は', $year, '年', $month, '月', $day, "日です。<br>\n";
print '今年は残り';
print '今日も含め', &RemainderDays($year,$month,$day,1), '日、';
print '今日を含めないと', &RemainderDays($year,$month,$day), '日しかありません。';
exit;
sub RemainderDays {
my($year, $month, $day, $flag) = @_;
my $remainderdays = 0;
my %monthdays = (1=>31, 2=>'', 3=>31, 4=>30, 5=>31, 6=>30, 7=>31, 8=>31, 9=>30, 10=>31, 11=>30, 12=>31);
if (($year % 4 == 0 && $year % 100 != 0) || ($year % 400 == 0)) {
$monthdays{2} = 29;
} else {
$monthdays{2} = 28;
}
foreach my $key (reverse(1..12)) {
last if ($month == $key);
$remainderdays += $monthdays{$key};
}
$remainderdays += ($monthdays{$month} - $day);
if ($flag) {
$remainderdays += 1;
}
return $remainderdays;
}
__END__
Perl/CGIプログラムサンプル はこちらに設置してあります。
このPerl/CGIプログラムサンプルにアクセスすると、本日の年月日と、その年が終わるまでの残りの日数を表示します。
年が終わるまでの日数は、今日を含めた場合と含めない場合の両方が表示されます。
Perl/CGIプログラム説明
Perl/CGIプログラムサンプルのコードについて説明します。
メイン処理
メイン処理では、本日が何年何月何日であるかを取得し、そこを基準にこの年の残りの日数を算出しています。
今日の年月日を取得するには、 localtime関数 を使います。
localtime関数の引数にtime関数から返される値を指定することにより、本日が何年何月何日であるかを取得できます。
しかし、localtime関数から返される値というのは 配列 形式になっているので、そこから年・月・日を表しているデータを取り出す必要があります。
年・月・日を表すデータは6・5・4番目の要素に格納されています。
添え字は0からはじまるので、添え字番号3・4・5を指定して取り出します。
これで、 変数 「$year」には年、「$month」には月、「$day」には日のデータが格納されました。
さらに、値を補正する必要があるので、年を表す「$year」には1900を、月を表している「$month」には1を足します。
あとは、RemainderDays関数で指定した年月日(本日の年月日)を引数にして、その年の残りの日数を計算させ表示させています。
RemainderDays関数
サブルーチン RemainderDaysについて説明します。
概要
RemainderDays関数は、指定された月日から、その年の末日(12月31日)までの残り日数を算出します。
引数は年・月・日・フラグ、戻り値は引数で指定した月日から同じく引数で指定した年の末日までの残り日数です。
Perl/CGIプログラムサンプルでは、わかりやすくするために今年にしていますが、過去の年でも未来の年でも、指定した月日からその年の末日までの残り日数を算出できます。
もちろん、実際に存在する年月日を指定する必要があります。
なので、以前紹介したような「 指定した年月日が存在するかを調べる方法 」などを使って、指定の年月日のチェックプロセスを用意しておくことが理想的です。
第4引数のフラグは、同じ引数で指定した日(Perl/CGIプログラムサンプルでは本日)を含めるかどうかを指定するものです。
1を指定した場合は、指定した日(Perl/CGIプログラムサンプルでは本日)を含めます。
「print '今日も含め', &RemainderDays($year,$month,$day,1), '日、';」
何も指定しない場合は含まれません。
「print '今日を含めないと', &RemainderDays($year,$month,$day), '日';」
Perl/CGIプログラムサンプルでは、print関数で引数を直接出力させていますが、もちろん スカラ変数 で受け取ることもできます。
トレース
RemainderDays関数の処理の流れについて解説します。
まず、引数で指定された年の各月が何日あるのかを定義します。
その際、 うるう年を考慮する ことがポイントです。
if文が成立 したときはうるう年です。
こうして各月の日数がわかったら、 foreachループ で12月から引数で指定された前の月まで、各月分の日数をたし合わせます。
引数に指定された月になったら、if文が成立するのでlast関数でループを抜けます。
あとは、引数で指定された月の日数から、第3引数に指定された日を引いた残りを足して完成です。
もし、第4引数のフラグのif文が成立したら、1日分足します。
これでRemainderDays関数終了です。