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

Hi.

I need to verify the validity of a date before it's written to a db. I've tried using the timelocal() function, but this one just exits the program when it finds the date is invalid. I would like to output my own error message.

How can I do this?

Thanks,
Ralph.

Replies are listed 'Best First'.
Re: Validating Dates
by IlyaM (Parson) on Feb 26, 2002 at 21:12 UTC
    timelocal doesn't exit on invalid date. It dies which can be trapped with eval. Also please note that timelocal doesn't die for some invalid dates. So it is good idea to check if localtime(timelocal(...)) returns same date.

    I've been using this subroutine in my code to validate dates:

    # checks if date is valid sub validate { use Time::localtime; use Time::Local qw(timelocal_nocheck); my $day = $shift; my $month = $shift; my $year = $shift; my $local; eval { $local = localtime(timelocal_nocheck(0, 0, 0, $day, $month - 1, $year)); }; if($@) { if($@ =~ /^Can't handle date/) { return 0; } else { die $@; } } my $c_day = $local->mday; my $c_month = $local->mon + 1; my $c_year = $local->year + 1900; return($day == $c_day and $month == $c_month and $year == $c_year) +; }

    --
    Ilya Martynov (http://martynov.org/)

Re: Validating Dates
by jlongino (Parson) on Feb 26, 2002 at 21:39 UTC
    Another method is to use the Date::Calc module:
    use strict; use Date::Calc qw(check_date); ## my ($month, $day, $year) = (2, 29, 2036); ## valid my ($month, $day, $year) = (2, 29, 2037); ## invalid, will set to d +efaults ## You could use dynamic date values instead my ($def_month, $def_day, $def_year) = (2, 7, 2002); if (not check_date ($year, $month, $day)) { print "Invalid date was entered ($month/$day/$year)! ", "Default date will be used instead.\n"; ($month, $day, $year) = ($def_month, $def_day, $def_year); } print "Using date: $month/$day/$year\n";

    --Jim