曜日を判定するプログラム

30分プログラム、その402。日付を与えると曜日を返す関数を書いてみた。
本当はカレンダーを作るつもりだったけど、整形して表示する時間はなかった。

使い方

# 1970/1/1が基準
$ perl cal.pl 1970 1 1
Thu

# 今日は水曜日
$ perl cal.pl 2008 10 29
Wed

ソースコード

#! /usr/bin/perl
# -*- mode:perl; coding:utf-8 -*-
#
# cal.pl -
#
# Copyright(C) 2008 by mzp
# Author: MIZUNO Hiroki / mzpppp at gmail dot com
# http://howdyworld.org
#
# Timestamp: 2008/10/29 22:31:12
#
# This program is free software; you can redistribute it and/or
# modify it under MIT Lincence.
#

use strict;
use warnings;
use Data::Dumper;
use List::Util qw( sum );

sub is_leap($){
    my ($year) = @_;
    if($year % 400 == 0){
	1;
    }elsif($year % 100 == 0){
	0;
    }elsif($year % 4 == 0){
	1;
    }else{
	0;
    }
}

sub days_of_month($$){
    my ($year,$month) = @_;
    my @days = (31,"-", 31, 30, 31, 30,
		31, 31, 30, 31, 30, 31);
    if($month == 2){
	if(is_leap($year)){
	    29;
	}else{
	    28;
	}
    }else{
	$days[$month - 1];
    }
}

sub days_of_year($){
    my ($year) = @_;
    if(is_leap($year)){
	366;
    }else{
	365;
    }
}

sub wday_of_date($$$){
    my ($year,$month,$day) = @_;
    my $year_sum  = sum map { days_of_year $_  } (1970..$year-1);
    my $month_sum = sum map { days_of_month($year,$_) } (1..$month - 1);

    my $sum =  ($year_sum || 0) + ($month_sum || 0)  + $day - 1;
    ($sum  + 4) % 7;
}

sub format_wday($){
    my ($wday) = @_;
    my @name   = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
    $name[$wday];
}

my ($year,$month,$day) = @ARGV;
print format_wday(wday_of_date($year,$month,$day)),"\n";