in reply to simple stupid time question

I'd just write a simple routine to do it. Something like the following wouldn't be awful, in a dozen lines of code or so:
sub days_in_month { my $month = shift; my $year = shift; my @mdays = qw( 31 28 31 30 31 30 31 31 30 31 30 31 ); if ($month == 2) { if ($year % 4 == 0) { # normal leap year if ($year % 100 == 0) { # century year, not a leap year return 28 unless ($year % 400 == 0); # century AND leap year } return 29; } } return $mdays[$month - 1]; # fudge the index }

Update: Foggy and Adam contributed the current state of (now tested) not-so-bugginess. Seems like I should have actually *looked it up* in my library before I tried to recreate this wheel from memory.

I originally intended this to be straightforward teaching code, but Adam's second snippet is much better.

Replies are listed 'Best First'.
RE: RE: simple stupid time question
by Adam (Vicar) on Sep 14, 2000 at 22:45 UTC
    Your leap year code is still wrong. It should be:
    if ($month == 2) { if ( ( $year % 4 == 0 ) # normal leap year && ( ( $year % 100 != 0 ) # century year || ( $year % 400 == 0 ) # leap century ) ) { return 29; } }
    Also, you declare my $days = 0 but you don't use it.

    Update: All those parens are ugly, how about:

    if( 2 == $month ) { return 29 if 0 == $year % 4 and 0 != $year % 100 or 0 == $year % 400; }
    That works thanks to short circuitry and precedence. (yeah I could remove the 0 != part, but I wanted to retain explicit readability.)

    I think the leap year formula has become a frequently asked question, so I posted the answer here as well.

    Update: Chromatic's code will now work. It a slightly different way to look at it, using if and unless, but it works.

RE: RE: simple stupid time question
by Fastolfe (Vicar) on Sep 14, 2000 at 17:38 UTC
    Is it possible for a leap century to occur on a leap year? Couldn't you get 30 days in February as a result? I'm wondering if there isn't already a module that does this...

      Nope, you can't have a 30-day February specifically because the construct actually looks like:

      if ((($year % 4) = 0) && (($year % 100) != 0)) { $feb += 1; } #leap year elsif (($year % 400) = 0) { $feb +=1; } #leap century

      So, since a regular "leap year" doesn't occur at the end of a century, the two conditions are never simultaneously satisfied.

      Spud Zeppelin * spud@spudzeppelin.com