月末日を取得する

月末日を取得するを見て。私なら翌月1日から1日戻すというやり方をするなあと思って書いてみました。同じようにTime::Localモジュールのtimelocal関数を使っています。書き方は似せてみました。あんまり動作確認はしていないのでちゃんと動くかどうかは知りません。

日付の引き算ができるモジュールが使えばそっちを使った方が簡単ですけど標準モジュールにはなかったかな。

use strict;
use warnings;

print "(1)月末日を取得する。\n";
my $end_of_month_200802 = end_of_month( 2008, 2 );
print "2008年2月の月末日は$end_of_month_200802日です。\n";

# 月末日を求める関数。
sub end_of_month {
    my ( $year, $month ) = @_;
    return if !$year || !$month;
    
    $year -= 1900;
    
    # 翌月にする
    if ($month == 12) {
        $year++;
        $month = 0;
    }
    
    require Time::Local; # 日付の存在チェック用に使用
    my $tim = Time::Local::timelocal(0, 0, 0, 1, $month, $year);
    $tim -= 1; # 1秒引く
    
    return (localtime $tim)[3];
}

モジュールを使わずに地道に書くならこれ。

use strict;
use warnings;

print "(1)月末日を取得する。\n";
my $end_of_month_200802 = end_of_month( 2008, 2 );
print "2008年2月の月末日は$end_of_month_200802日です。\n";

# 月末日を求める関数。
sub end_of_month {
    my ( $year, $month ) = @_;
    return if !$year || !$month;
    
    my @mlast = ('dummy', 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    if ($month == 2) {
        if ( (($year % 4 == 0) and ($year % 100 != 0)) or ($year % 400 == 0) ) {
            $mlast[$month]++;
        }
    }
    
    return $mlast[$month];
}