in reply to perl basic count days between two dates
There are modules that will do this for you. I acknowledge you indicate you do not wish to use a module.
So the first step is to figure out the algorithm you wish to use. Grab pencil and paper (or a whiteboard for you youngins), and start trying to figure out how you would do the math by hand.
Then try to write code that would do the same thing you did by hand.
The number of things you are likely to overlook or get wrong are controllable in this example, but high enough to reward your use of a Module where someone else (or several someone elses) took the time to iron out the bugs for you.
But if you just gotta write the code yourself, Step 1 is to figure out how to do it by hand.
P.S. I would suggest researching Leap Year Rules. Assuming your needs do not extend to earlier than Friday, October 15, 1582 in Catholic countries, 1698 or 1752 in principalities headed by Protestants, or 1918 in Russia, a shortcut to use only the modern computation should suffice.
In that computation, the base assumption is that every year has 365 days unless it is declared to be a leap year, in which case it has 366.
More specifically, February would have 29 days rather than the hardcoded 28 you presume in your code.
Research the Leap Year Rules, and you should be able to devise a subroutine which can determine if any given year is a leap year.
From there, you should have all the tools you need to compute number of days between dates, given sufficient forethought to the construction of either your computational algorithms, or your foreach loops  or some combination thereof.
Update: Okay, fine, here's one example of the many things a module could do for you that you would have to grind through to do by hand:
sub isLeapyear
{
my ($year, @extraStuff) = @_;
if (!defined $year) { $year = 0; }
my $leapYearFlag = 0; # Assume not a leap year until proven
+ otherwise.
if ($year % 4) {
# Not divisible by 4. Cannot be a leap year.
$leapYearFlag = 0;
} else {
# Divisible by 4. Possibly a leap year.
if ($year % 100) {
# Is not divisible by 100. It is a leap year.
$leapYearFlag = 1;
} else {
# Is divisible by 100. May not be a leap year.
if ($year % 400) {
# Is not divisible by 400. Cannot be a leap year.
$leapYearFlag = 0;
} else {
# Is divisible by 400. IS a leap year.
$leapYearFlag = 1;
}
}
}
return $leapYearFlag;
}
Re^2: perl basic count days between two dates by talexb (Canon) on Oct 03, 2013 at 21:04 UTC 
There's always more than one way to do it .. I like to switch things around and test for the least likely outcome first .. check to see if the year is divisible by 400, then 100, and finally 4. I think it also makes the code a little more transparent, but everyone's got their own style ..
#!/usr/bin/perl
use strict;
use warnings;
my %testData = (
1900 => 0,
1904 => 1,
1972 => 1,
1973 => 0,
1999 => 0,
2000 => 1,
2001 => 0,
2004 => 1
);
{
foreach my $this ( keys %testData ) {
if ( $testData{$this} == leapYear($this) ) {
print "Correct  $this year "
. ( $testData{$this} ? "is" : "is not" )
. " a leap year.\n";
}
else {
print "Error with $this entry ..\n";
}
}
}
sub leapYear {
my $year = shift;
if ( $year % 400 ) {
if ( $year % 100 ) {
# 3. Simple case: it's a leap year if it's divisible by 4
return ( $year % 4 ) ? 0 : 1;
}
else {
# 2. If it's divisible by 100: it's not a leap year.
return 0;
}
}
else {
# 1. If it's divisible by 400: it's a leap year.
return 1;
}
}
I've numbered the comments to make it a little clearer which result might be returned first, although this could be made even clearer by reversing the meaning of the conditionals so that the routine looks like this:
sub leapYear {
my $year = shift;
if ( $year % 400 == 0 ) {
# 1. If it's divisible by 400: it's a leap year.
return 1;
}
else {
if ( $year % 100 == 0 ) {
# 2. If it's divisible by 100: it's not a leap year.
return 0;
}
else {
# 3. Simple case: it's a leap year if it's divisible by 4
return ( $year % 4 ) ? 0 : 1;
}
}
}
Alex / talexb / Toronto
Thanks PJ. We owe you so much. Groklaw  RIP  2003 to 2013.
 [reply] [d/l] [select] 
