今年の経過日数

今年がスタートして今日で何日目でしょうか?

元日(1月1日)から今日まで何日経過したかを調べる Perl/CGIプログラムを作成 してみましょう。

  1. Perl/CGIプログラム作成
  2. Perl/CGIプログラム説明

Perl/CGIプログラム作成

今年に入ってから今日が何日目に当たるかを調べる 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 '今日も含め', &LapsedDays($year,$month,$day,1), '日、';
print '今日を含めないと', &LapsedDays($year,$month,$day), '日経過しました。';
exit;


sub LapsedDays {
my($year, $month, $day, $flag) = @_;
my $lapseddays = 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 (1 .. 12) {
last if ($month == $key);
$lapseddays += $monthdays{$key};
}

$lapseddays += $day;

unless ($flag) {
$lapseddays -= 1;
}

return $lapseddays;
}

__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を足します。

あとは、LapsedDays関数で指定した年月日(本日の年月日)を引数にして、その年の元日から本日までの経過日数を計算させ表示させています。

LapsedDays関数

サブルーチン LapsedDaysについて説明します。

概要

LapsedDays関数は、指定された年の元日(1月1日)から、指定された月日までの経過日数を算出します。

引数は年・月・日・フラグ、戻り値は引数で指定した年の元日から同じく引数で指定した月日までの経過日数です。

Perl/CGIプログラムサンプルでは、わかりやすくするために今年にしていますが、過去の年でも未来の年でも、その年の1月1日から指定の月日までの経過日数を算出できます。

もちろん、実際に存在する年月日を指定する必要があります。

なので、前回紹介したような「 指定した年月日が存在するかを調べる方法 」などを使って、指定の年月日のチェックプロセスを用意しておくことが理想的です。

第4引数のフラグは、同じ引数で指定した日(Perl/CGIプログラムサンプルでは本日)を含めるかどうかを指定するものです。

1を指定した場合は、指定した日(Perl/CGIプログラムサンプルでは本日)を含めます。

「print '今日も含めると', &LapsedDays($year,$month,$day,1), '日、';」

何も指定しない場合は含まれません。

「print '今日を含めない場合は', &LapsedDays($year,$month,$day), '日';」

Perl/CGIプログラムサンプルでは、print関数で引数を直接出力させていますが、もちろん スカラ変数 で受け取ることもできます。

トレース

LapsedDays関数の処理の流れについて解説します。

まず、引数で指定された年の各月が何日あるのかを定義します。

その際、 うるう年 を考慮することがポイントです。

if文が成立 したときはうるう年です。

こうして各月の日数がわかったら、 foreachループ で1月から引数で指定された前の月まで、各月分の日数をたし合わせます。

引数に指定された月になったら、if文が成立するのでlast関数でループを抜けます。

あとは、第3引数に指定された日(日数)を足して完成です。

もし、第4引数のフラグが指定されてない、もしくは0の場合は、1日分ひきます。

これでLapsedDays関数終了です。