Perl でカレンダーモジュール

プログラミングは、ここ数年全然していないから、C も Perl も忘れちまっている...かろうじておぼろげに分かるのは Vim Script ぐらいになってしまった。一から Perl を勉強せねば。
ということで、カレンダー・スケジュールに必要なモジュールを作ってみる。
まず、現在時刻の取得は比較的簡単。

#------------------------------------------------------------------------------
# 現在時間所得
#------------------------------------------------------------------------------
sub time{
    ($sec,$min,$hour,$today,$mon,$year,$wday) = localtime(time);
    @week    = ('日','月','火','水','木','金','土');
    $week = $weekday[$wday];
    $mon++;
    $year = 1900 + $year;
}

カレンダーのためには「うるう年」を判定して、2月の最終日を取得しないといけない...。

#------------------------------------------------------------------------------
# うるう年判定(2月の最終日を返す)
#   $bis = get_bis(西暦);
#------------------------------------------------------------------------------
sub get_bis {
    local($year) = @_;
    $year = int($year);
    $bis = 28;
    if ( ( $year % 4 == 0) && ( ( $year % 100 != 0) || ($year % 400 == 0))) {
        $bis = 29;
    }
    return ($bis);
}

指定した日の曜日取得は、Zeller の公式でラクチンだね。

#------------------------------------------------------------------------------
# 曜日取得(Zellerの公式)
#   (日,月,火,水,木,金,土) = (0,1,2,3,4,5,6)
#   $d_week = get_week(西暦,月,日);
#------------------------------------------------------------------------------
sub get_week {
    local($year, $mon, $day) = @_;
    if ($mon == 1 || $mon == 2) {
        $year--;
        $mon += 12;
    }
    local($day_of_the_week) = int (
        $year
        + int ($year/4)
        - int ($year/100)
        + int ($year/400)
        + int ( ( 13*$mon+8)/5)
        + $day
    ) % 7;
    return ($day_of_the_week);
}

春分の日秋分の日も計算させないと...。やっと参考になるページを見つけて、計算させることが出来た...。

#------------------------------------------------------------------------------
# 春分の日所得
#   $spring = get_spring(西暦);
#------------------------------------------------------------------------------
sub get_spring {
    local($year)=@_;
    if ( ( $year < 1980) || ($year > 2099)) {
        $autumn = 0;
    }
    else {
        $spring=int(20.8431+0.242194*($year-1980)-int( ( $year-1980)/4));
    }
    return ($spring);
}
#------------------------------------------------------------------------------
# 秋分の日所得
#   $autumn = get_autumn(西暦);
#------------------------------------------------------------------------------
sub get_autumn {
    local($year)=@_;
    if ( ( $year < 1980) || ($year > 2099)) {
        $autumn = 0;
    }
    else {
        $autumn=int(23.2488+0.242194*($year-1980)-int( ( $year-1980)/4));
    }
    return ($autumn);
}

ハッピーマンデー...これが一番大変。紙のカレンダーとにらめっこして、なんとか作ることが出来た...。

#------------------------------------------------------------------------------
# ハッピーマンデー日取得
#   $holiday = happymonday(西暦,月,第何週);
#------------------------------------------------------------------------------
sub get_happymonday {
    local($year,$mon,$w_no)=@_;
    if ( ($tmp = int(&get_week($year,$mon,1))) <= 1) {
        $tmp = ( ( (int($w_no) - 1 ) * 7 ) + 2) - $tmp;
    }
    else {
        $tmp = ( ( int($w_no) * 7 ) + 2) - $tmp;
    }
    return ($tmp);
}

あとは、休日一覧ファイルを用意して....

1   1   元日
1   HM2 成人の日
2   11  建国記念の日
3   SPR 春分の日
4   29  昭和の日
5   3   憲法記念日
5   4   みどりの日
5   5   こどもの日
7   HM3 海の日
9   HM3 敬老の日
9   AUT 秋分の日
10  HM2 体育の日
11  3   文化の日
11  23  勤労感謝の日
12  23  天皇誕生日

ファイルを読み込ませて、ハッピーマンデーと春分秋分の日を反映させる。

#------------------------------------------------------------------------------
# 休日所得
#   $holiday = get_holiday(西暦,ファイル名);
#------------------------------------------------------------------------------
sub get_holiday {
    local($year,$file)=@_;
    open(IN,"$file") || &error('エラー','$fileファイルが開けません');
    @hd = ;
    close(IN);
    foreach (@hd) {
        $_=~s/\n//;
        ($mon,$day,$str) = split;
        $result=$day;
        if ( (  $day eq "HM2" ) || ( $day eq "HM3" )) {
            $day=~s/HM//ig;
            $result = &get_happymonday($year,$mon,int($day));
            $_=~s/HM$day/$result/;
        }
        if ( $day eq "SPR" ) {
            $result = &get_spring($year);
            $_=~s/$day/$result/;
        }
        if ( $day eq "AUT" ) {
            $result = &get_autumn($year);
            $_=~s/$day/$result/;
        }
    }
    return (@hd);
}

素人だから、迂遠な手法ばかりかもしれないけど、なんとか動いているようだ。
後は、このモジュールを利用して、HTML にカレンダー出力する際に休日を色分けすればよいかな。色設定自体は CSS を使用するようにすれば、コーディングは更に楽になるね。
と、思いきや....「振替休日」を考慮していなかった!!!
明日の晩は、振替休日から取り組まないといけないな....。