Subject: | Incorrect day of week results |
Certain days for large groups of years produce incorrect day_of_week results.
I was testing Date::Simple version 3.01 on a machine running red hate enterprise linux ws. Perl 5.8.0 is installed on this machine.
I've attached as test program to illustrate these bugs.
#!/usr/local/bin/perl -w
################################################################################
################################################################################
## Author: Anil Natha
################################################################################
################################################################################
## SCRIPT INCLUDES AND DECLARATIONS
use strict;
use diagnostics;
use Date::Simple;
################################################################################
################################################################################
## HEADER INFORMATION
print "Content-type: text/html\n\n";
################################################################################
################################################################################
## MAIN PROCEDURE
my @dayNames = ( 'Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday');
my @dayCount = ( 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
## -----------------------------------------------------------------------------
## -----------------------------------------------------------------------------
print <<HEADER;
<html>
<head>
<title>Date Test</title>
<style type="text/css">
body,table,tr,table,font { font-family: Arial,Verdana,Helvetica; font-size: 8pt; }
</style>
</head>
<body>
<table width='550' border='1'>
<th>Date</th>
<th>My Method</th>
<th>Date::Simple</th>
<th>Test</th>
HEADER
for( my $year = 1580; $year <= 2004; $year++ ) {
for( my $month = 1; $month <= 12; $month++ ) {
for( my $day = 1; $day <= $dayCount[$month]; $day++ ) {
testDate($month,$day,$year);
}
if( $month == 2 && isLeapYear($year) ) {
testDate($month,29,$year);
}
}
}
print <<FOOTER;
</table>
</body>
</html>
FOOTER
################################################################################
################################################################################
## -----------------------------------------------------------------------------
## -----------------------------------------------------------------------------
sub testDate {
my($month,$day,$year) = @_;
my $dayIndex = dayOfWeek($month,$day,$year);
my $dayObject = new Date::Simple($year,$month,$day);
$dayObject = $dayObject->day_of_week;
print " <tr valigh='center' align='center'>";
print " <td>$month/$day/$year</td>\n";
print " <td>" . $dayNames[$dayIndex] . "</td>\n";
print " <td>" . $dayNames[$dayObject] . "</td>\n";
if( $dayIndex != -1 ) {
if( $dayIndex != $dayObject ) {
print " <td><font color='#990000'>Invalid</font></td>\n";
} else {
print " <td><font color='#006600'>Valid</font></td>\n";
}
} else {
print " <td><font color='#006600'>Error</font></td>\n";
}
print " </tr>\n";
}
## -----------------------------------------------------------------------------
## -----------------------------------------------------------------------------
sub dayOfWeek {
my($month,$day,$year) = @_;
my $a = int((14 - $month) / 12);
my $y = $year - $a;
my $m = $month + 12 * $a - 2;
if( $year < 1582 || ($year == 1582 && ( $month < 10 || ($month == 10 && $day <= 4) ) ) ) {
## OUTPUT DAY BASED ON JULIAN CALENDAR
return( (5 + $day + $y + int($y / 4) + int((31 * $m) / 12)) % 7 );
} elsif( $year > 1582 || ($year == 1582 && ( $month > 10 || ($month == 10 && $day >= 15) ) ) ) {
## OUTPUT DAY BASED ON GREGORIAN CALENDAR
return( ($day + $y + int($y / 4) - int($y / 100) + int($y / 400) + int((31 * $m) / 12)) % 7 );
} else {
## RETURN ERROR
return(-1);
}
}
## -----------------------------------------------------------------------------
## -----------------------------------------------------------------------------
sub isLeapYear {
my ($year) = @_;
if ( ($year % 4 == 0) && ( ($year % 100) || ($year % 400 == 0) ) ) {
return(1);
} else {
return(0);
}
} # end subroutine isLeapYear
## -----------------------------------------------------------------------------
## -----------------------------------------------------------------------------
################################################################################
################################################################################
## CLOSING INSTRUCTION CALLS
exit;