Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

checking for valid date

by alandev (Scribe)
on Jul 30, 2006 at 06:34 UTC ( [id://564594]=perlquestion: print w/replies, xml ) Need Help??

alandev has asked for the wisdom of the Perl Monks concerning the following question:

hi monks i need to check whether a valid date is passed in yyyymmdd format . thanks monks

Replies are listed 'Best First'.
Re: checking for valid date
by GrandFather (Saint) on Jul 30, 2006 at 07:02 UTC

    There are a pile of Date manipulation modules available for Perl. The big hammer is Date::Manip. Possibly the way to validate your date string is first to chop it up assuming that the format is correct:

    if ($yyyymmdd !~ /(\d{4})(\d\d)(\d\d)/) { print "Bad data string provided: $yyyymmdd\n"; return 0; } my ($year, $month, $day) = ($1, $2, $3); ...

    You can then check that the year, month and day are within the expected ranges and finally validate the full date by using Date::Manip.


    DWIM is Perl's answer to Gödel
Re: checking for valid date
by planetscape (Chancellor) on Jul 30, 2006 at 13:40 UTC
Re: checking for valid date
by Ieronim (Friar) on Jul 30, 2006 at 10:31 UTC
    The standard module Time::Local will do the trick.
    use Time::Local; my $date = ' 19990230'; # 30th Feb 1999 $date =~ s/\s+$//; $date =~ s/^\s*//; my ($year, $month, $day) = unpack "A4 A2 A2", $date; eval{ timelocal(0,0,0,$day, $month-1, $year); # dies in case of bad date + 1; } or print "Bad date: $@";
    UPD: But this won't work for valid dates less than Jan 1 1970 and greater than Jan 19 2038. If you need to check dates outside this range, try Date::Manip.

         s;;Just-me-not-h-Ni-m-P-Ni-lm-I-ar-O-Ni;;tr?IerONim-?HAcker ?d;print
Re: checking for valid date
by ambrus (Abbot) on Jul 30, 2006 at 12:50 UTC

    I'll do this in two steps. First I'll check that the date is indeed eight digits, then I'll check if it refers to a valid date with the Date::Manip module (so this will fail with historical dates using the Julian calendar).

    perl -we 'use Date::Manip; sub valid_yyyymmdd { $_[0] =~ /^(\d{8})$/ a +nd ParseDate($1) and 1; } valid_yyyymmdd($_) and print "$_\n" for qw" +20060630 20060631 20060730 20060731 20060732 2006.07.30 06.07.31";'
    Output:
    20060630 20060730 20060731
Re: checking for valid date
by davidrw (Prior) on Jul 30, 2006 at 20:03 UTC
    for completeness, here's a Date::Calc solution:
    use Date::Calc qw/check_date/; my @date = $yyyymmdd =~ /^(\d{4})(\d{2})(\d{2})$/; die "ERROR: bad date '$yyymmdd'" unless check_date(@date); printf "Valid (y,m,d)=(%d,%d,%d)\n", @date;
Re: checking for valid date
by explorer (Chaplain) on Jul 30, 2006 at 13:57 UTC

    DateTime modules have almost all responses...

    use DateTime::Format::ISO8601; eval { $date = DateTime::Format::ISO8601->parse_datetime("20061730"); }; if ( $@ ) { print "ERROR: date not valid" };
Re: checking for valid date
by TedPride (Priest) on Jul 30, 2006 at 16:54 UTC
    Just because I like to roll my own:
    use strict; use warnings; while (<DATA>) { chomp; print "$_ : ", validate($_), "\n"; } BEGIN { my @mdays = (0,31,28,31,30,31,30,31,31,30,31,30,31); sub validate { no warnings; my ($year, $month, $day) = $_[0] =~ m/^(\d{4})(\d{2})(\d{2})$/ +; my $nyear = (localtime())[5] + 1900; ##### Year range is 10 years on either side of current year ##### Also exits if m// returned nothing return if $year < $nyear - 10 || $year > $nyear + 10; return if $month < 1 || $month > 12; ##### Leap year conditions if ($month == 2) { if ($year % 4 != 0) { $mdays[2] = 28; } elsif ($year % 400 == 0) { $mdays[2] = 29; } elsif ($year % 100 == 0) { $mdays[2] = 28; } else { $mdays[2] = 29; } } return if $day < 1 || $day > $mdays[$month]; return 1; } } __DATA__ 1234567 19991203 20051303 20051232 20040229 20050229 20401223

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://564594]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-23 20:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found