http://qs1969.pair.com?node_id=32583

Adam has asked for the wisdom of the Perl Monks concerning the following question: (dates and times)

How do I determine if a given year is a leap year?

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: Leap Year
by Agyeya (Hermit) on May 17, 2004 at 10:22 UTC
    The Date::Leapyear module will tell if a year is a (Gregorian) leap year:
    use Date::Leapyear; if ( isleap(yyyy) ) { ... }
    The function isleap(yyyy) returns 1 in a leap year, 0 otherwise.

      And the source code for Date::Leapyear reads:

      sub isleap { my ($year) = @_; return 1 if (( $year % 400 ) == 0 ); # 400's are leap return 0 if (( $year % 100 ) == 0 ); # Other centuries are not return 1 if (( $year % 4 ) == 0 ); # All other 4's are leap return 0; # Everything else is not }

      which is already a provided answer. The same semi-correct formula is also used in Astro::Time and DateTime. Unless someone goes to the touble of encoding the entire FAQ, stick with the original answer. I like CPAN as much as the next Monk, but some modules are wasteful.

      Updated: I do note that the DateTime::Calendar::* modules at least make some attempt at dealing with cultural and temporal variances ...


      If anyone needs me I'll be in the Angry Dome.
        Yup. This was probably a pretty wasteful module.
        --
        Tommy Butler, a.k.a. TOMMY
        
Re: Leap Year
by mojotoad (Monsignor) on Aug 12, 2003 at 06:41 UTC
    DateTime offers an is_leap_year method for datetime objects.

    They also provide leapsecond information via the DateTime::LeapSecond class, if you're into that.

    Matt

Re: Leap Year
by TheHobbit (Pilgrim) on Apr 17, 2002 at 16:08 UTC
    Well, may be... but your answer is false:).

    Let's be precise: nowadays, your answer is right, but only since Gregorian reform, which has been take into account at different times in differents countries. Before that, and since 45BC, there was a leap year in every year divisible by 4 (NOTE: 45BC is year -44).

    Even that isn't exatly true... At the beginning people did not understand what "once in 4 years" meant, and there was a period (between 45BC and 9BC) where there was a leap year every 3 years. Followed by a period (between 8BC and 8AD) where there was no leapyear at all.

    See the Calendar FAQ .


    TheHobbit
Re: Leap Year
by Sol-Invictus (Scribe) on Feb 06, 2004 at 08:23 UTC
    The exact dates when countries (that use the Western calendar) adopted the Gregorian version varies. See this section of the Calendar FAQ
Re: How do I determine if a given year is a leap year?
by DeadPoet (Scribe) on Jan 08, 2011 at 18:16 UTC

    Not my work, but a great example:

    sub IsLeapYear { my $year = shift; return 0 if $year % 4; return 1 if $year % 100; return 0 if $year % 400; return 1; }

    The IsLeapYear subroutine is called with a year number, like

    IsLeapYear(2006);

    The function returns a true value if the year number is a leap year, false otherwise.

    Get the correct number of days in February for the given year:

    my $days_in_February = IsLeapYear($year) ? 29 : 28;

      I must not have had sufficient coffee in my bloodstream when reading this, as the first few times I read through it I stumbled on overlooked the fact that % returns a false value when the year is appropriately divisible. Thanks to Corion for smacking me with a the clue-by-four of understanding.

      As moritz stated in the CB, think of it as foo() if (($a % X) == 0)

      Posted to hasten others to the "oh yeah" moment.

      --MidLifeXis

RE (tilly) 1: Answer: Leap Year
by tilly (Archbishop) on Sep 15, 2000 at 13:24 UTC
    Note that the answer to this question depends on your calendar. The standard Unix cal program assumes that the calendar switched from the Julian to the Gregorian in 1752. (Hence leading to an odd-looking September. BTW the man page I have does not mention the fact that the date chosen is English-centric. The bored and curious may want to see the actual statute or general background on the change.) Prior to that the century and four century correction terms did not apply.

    Incidentally the solar year is currently 365d 5h 48m 46.069s which is not fully accounted for by the Gregorian Calendar so there is talk of some day adding another correction term. This is unlikely to be an issue in the lifetimes of anyone reading this though. :-)

      Yes. I assumed that you were using the Gregorian calander.
      (regardless of what year your country switched to it.)

      Protestant England switched to the Gregorian in 1752, but the Catholic nations switched in 1582. Other groups did not switch until as late as the 20th century. Calanders are funny things in that they represent a societal contract to delude ourselves as a group that we know what time it is.

      Reality check: We do not know what time it is because time is relative. There are two important facts:

      1. Time moves forward only. When did time begin? We don't know, so we make up a start point. (This is, admitadly, a secular argument*, but as my second point reveals, even the non-secular "dawn of time" does not work either.)
      2. How do you measure time? The US Navy does it with 54 atomic clocks in dispersed vaults, including 10 hydrogen masers and 44 cesium beam devices. In other words, they picked something that does something at a reasonably steady rate, and the measured it. But even that is not trully precise. As Einstein proved, time progresses at different rates dependant on the velocity of the observer. Add that into gravitational forces altering our orbit around the sun, and suddenly every year is a different length.
      Time is the great cosmic joke. It is much easier to buy into the group delusion that we know what time it is. It makes it possible to schedule things like trains, tele-conferences, lunch. What I'm saying, Tilly, is that calculating anything having to do with time requires some basic assumptions from the parties involved. The most prevelant calander on the planet is the Gregorian, so we use Gregory's rule and if enough different governing bodies ever agree to muck with that and 'fix' the inherint errors, then this will change.

      But what really needs fixing? Does it matter (really) if the month of December happens to fall in the summer in the year 5300 something??** People have been tinkering with calanders since we first started making them. (Julieus Ceaser had July, the month with the most daylight, named after him. Augustus Ceaser followed him both as Emporer and Month maker and took the month with next greatest amount of sun light... he even took a day from February to bring August up to 31, matching July. )

      But I digress, we are here to talk Perl, not to waste time talking about time. You included some good links, I suggest that people interested in this stuff read them. Another good one is the Claus Tondering Calander FAQ.

      *An interesting point that I read somewhere was that the Muslim calander actually shifts the months around through the year, so that Ramadan will occur during all the seasons in a person life.

      **As chromatic mentioned to me in a chatterbox msg, December fell in the summer this year too... south of the Equator. More evidence that calanders are contrived.

Re: How do I determine if a given year is a leap year?
by Anonymous Monk on Oct 26, 2004 at 15:46 UTC
    poop

    Originally posted as a Categorized Answer.

Re: Leap Year
by Anonymous Monk on Mar 01, 2004 at 10:32 UTC
    This appears to be a C solution...and an incorrect one at that.
    /* == is yr a leap year == */ int IsLeapYear(int Year) /* Return SUCCESS if Year is a leap year, FAIL otherwise */ { if ((Year % 4 == 0) && (Year % 4000 != 0) && ((Year % 100 != 0) || (Year % 400 == 0))) return(SUCCESS); return(FAIL); }

    Originally posted as a Categorized Answer.