Calculate the day of the week for a give date. 0 is Sunday. Valid from 14 September 1752 onwards.

Algorithm by Tomohiko Sakamoto from the C FAQ, section 20.31.

###################################################################### +######### # # day_of_week($year, $month, $day) # # Valid from 14 September 1752 onwards. $month and $day are 1 indexed. # # Returns: 0 .. 6 where 0 is Sunday. # # Algorithm by Tomohiko Sakamoto from the C FAQ, section 20.31. # sub day_of_week { my ($year, $month, $day) = @_; my @offset = (0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4); $year -= $month < 3; return ($year + int($year/4) - int($year/100) + int($year/400) + $offset[$month-1] + $day) % 7; }

See also Day of week for an arbitary date using core modules, Date::Calc, Date::Manip, Time::Piece.

Replies are listed 'Best First'.
Re: Day of the week
by RMGir (Prior) on Apr 11, 2003 at 11:50 UTC
    Nice one...

    Here's a test case for you; it lets you crosscheck your sub against localtime for localtime's range.

    #!/usr/bin/perl -w use strict; sub day_of_week { my ($year, $month, $day) = @_; my @offset = (0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4); $year -= $month < 3; return ($year + int($year/4) - int($year/100) + int($year/400) + $offset[$month-1] + $day) % 7; } my $i=0; for(my $time=1; $time<2**31; $time+=86400) { my ($mday,$mon,$year,$wday)=(localtime($time))[3..6]; $mon++; $year+=1900; my $day=day_of_week($year,$mon,$mday); # progress info... print ((scalar localtime($time))," $day, $wday\n") unless ($i++%10 +00); if($day != $wday) { print "Mismatch between sub ($day) and localtime ($wday) for " +, (scalar localtime($time)),"\n"; } }
    Obviously needs a bit of work to be recast as a test case, sorry.

    Your routine passes on my system :)
    --
    Mike


      Thanks. I did test it myself as well. ;-)

      See below.