http://www.perlmonks.org?node_id=614940


in reply to Simple Date Validation

I have the following which I converted from C a long time ago when I was very new to Perl. It was set up for the UK so the Julian/Gregorian change is in 1752.

# ------ sub isLeap # ------ { my $year = shift or croak "isleap(): no year supplied\n"; croak "isLeap(): year not numeric\n" unless $year =~ /^\d+$/; return 0 if $year % 4; return 1 if $year < 1753; return 1 if $year % 100; return 1 unless $year % 400; return 0; } # ------- sub valDate # ------- { my($year, $month, $day) = @_; return 0 unless $year =~ /^\d+$/ and $month =~ /^\d+$/ and $day =~ /^\d+$/; my $daysinm = [ [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]]; return 0 if $year < 1 or $year > 9999; return 0 if $month < 1 or $month > 12; return 0 if $day < 1 or $day > $daysinm->[isLeap($year)]->[$month - 1]; return 0 if $year == 1752 and $month == 9 and ($day > 2 and $day < 14); return 1; }

It works for any year from 1 to 9999 (not y10k compliant I'm afraid ;-)

I hope this is of use.

Cheers,

JohnGG

Replies are listed 'Best First'.
Re^2: Simple Date Validation
by Not_a_Number (Prior) on May 11, 2007 at 16:16 UTC
    not y10k compliant I'm afraid ;-)

    Not Julian-compliant either!

    You need to change

    return 1 if $year < 1753

    to

    return 1 if $year < 1753 and not $year %4;

    </nitpick>

    Update: Memo to /me: Test before you post! (See below.)

      No, that's not necessary at all.

      By the time we reach that line in the subroutine we are only left with years that are divisible by 4 because of the line above, which is

      return 0 if $year % 4;

      so your amendment, and not $year %4, is superfluous.

      Cheers,

      JohnGG