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
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs