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

Reply via email to