Michael Louie Loria wrote: > I'm tesing the Text::ParseWords > > I'm new in Perl and I'm a little bit confused with the PATTERNS > option but I'm learning it. > > Is this code good for checking valid date in the format YYYY-MM-DD? > or do you have any other suggestions
What's with the ~'s starting each line ? > sub isvaliddate { > ~ my $input = shift; > ~ if ($input =~ m!^((?:19|20)\d\d)[- /.](0[1-9]|1[012])[- > /.](0[1-9]|[12][0-9]|3[01])$!) { > ~ # At this point, $1 holds the year, $2 the month and $3 the day > of the date entered > ~ if ($3 == 31 and ($2 == 4 or $2 == 6 or $2 == 9 or $2 == 11)) { > ~ return 0; # 31st of a month with 30 days > ~ } elsif ($3 >= 30 and $2 == 2) { > ~ return 0; # February 30th or 31st > ~ } elsif ($2 == 2 and $3 == 29 and not ($1 % 4 == 0 and ($1 % 100 > <> 0 or $1 % 400 == 0))) { > ~ return 0; # February 29th outside a leap year > ~ } else { > ~ return 1; # Valid date > ~ } > ~ } else { > ~ return 0; # Not a date > ~ } > } > > The link for that code is > http://www.regular-expressions.info/dates.html coz you might not > understand the code # test a few examples: foreach ('2005-02-30', '2005-04-31', '2005-13-30', '2005-02-35', '2005-02-00', '2005-01-30',) { my $bool = isvaliddate ($_); # your code printf "$_ is%s valid\n", $bool ? '' : ' not'; $bool = is_valid_date ($_); # alternative code printf "$_ is%s valid\n", $bool ? '' : ' not'; } exit; # Reformatted it and changed <> to != and it seems ok to me : sub isvaliddate { my $input = shift; # you could just use substr's and length() here instead of a RE # for hopefully a little more speed : # return 0 if length $input != 10 or substr ($input, 4, 1) ne '-' # or substr ($input, 7, 1) ne '-'; # my $year = substr $input, 0, 4; # my $month = substr $input, 5, 2; # my $day = substr $input, 8, 2; # then replace $1, $2 and $3 with $year, $month and $day if ($input !~ m#^((?:19|20)\d\d)[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$#) { return 0; # Not a date } # $1 = year, $2 = month $3 = day of month if ($3 == 31 and ($2 == 4 or $2 == 6 or $2 == 9 or $2 == 11)) { return 0; # 31st of a month with 30 days } elsif ($3 >= 30 and $2 == 2) { return 0; # February 30th or 31st } elsif ($2 == 2 and $3 == 29 and not ($1 % 4 == 0 and ($1 % 100 != 0 or $1 % 400 == 0))) { # <> 0 was wrong for != 0 return 0; # February 29th outside a leap year } return 1; # Valid date } This should work as well (maybe better) - letting the system do most of the grunt work but is much slower than yours : sub is_valid_date { my $datestr = shift; require Time::Local; my @d = (0, 0, 12, (split /-/, $datestr)[2, 1, 0]); $d[4]--; $d[5] -= 1900; eval "Time::Local::timegm ([EMAIL PROTECTED])"; # see if it converts to epoch ok return $@ ? 0 : 1; # return 0 if error else 1 } __END__ -- ,-/- __ _ _ $Bill Luebkert Mailto:[EMAIL PROTECTED] (_/ / ) // // DBE Collectibles Mailto:[EMAIL PROTECTED] / ) /--< o // // Castle of Medieval Myth & Magic http://www.todbe.com/ -/-' /___/_<_</_</_ http://dbecoll.tripod.com/ (My Perl/Lakers stuff) _______________________________________________ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs