$Bill Luebkert wrote: > 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__ > >
Sorry for the ~ character. My MUA added it. I have tested the code and is really good but I had to change a line of code elsif ($2 == 2 and $3 == 29 and not ($1 % 4 == 0 and ($1 % 100 <> 0 or $1 % 400 == 0))) to elsif ($2 == 2 and $3 == 29 and ($1 % 4 != 0 and ($1 % 100 == 0 or $1 % 400 != 0))) coz I had errors with the former. I think the culprit was the NOT [ not ($1 % 4 == 0 and ($1 % 100 <> 0 or $1 % 400 == 0) ]. Thanks again Michael Louie Loria __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
signature.asc
Description: 3412282408-signature.asc
_______________________________________________ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs