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

I've been kicking around this stuff pretty much all day, so I decided to get some help. Basically I need to check a date format with regex in a cgi application. Here is my code:
if ($dated =~ m/^[0-3][0-9]\/[0-1][0-9]\/[1-2][0-9][0-9][0-9]$/) { } else { #User entered an invaild date. $passfail = 0; $errmsg = 'Unable to use date format. Please use "MM/DD/YYYY" or MM-DD +-YYYY for the Date Delivered Field'; $errtitle = 'Validation Error'; $seconds = 7; }
I don't really understand regex no matter how much reading I do, its just very difficult to understand at a glance. I will also be needing to check $dated to see if its blank. So it could either be MM/DD/YYYY or nothing. I'm sure I'm getting close, but no matter what that is always doing the "else statement"

Replies are listed 'Best First'.
Re: Quick Regex Question
by Herkum (Parson) on May 07, 2007 at 20:22 UTC

    There is a module called Data::FormValidator::Constraints::DateTime that is used with Data::FormValidator. You can use this to validate the date that you are trying to do.

    The reason that this is better than a regular expression is that you can have a valid regular expression and an invalid date. Example: 02/31/2007. This date just cannot exist. Something trickier would be 02/29/2007. Now you have evaluate if it is a leap year or not.

    So use a pre-existing module to validation instead of a regular expression or one of your own. The module I showed up may not be the best option for you but I am sure that there are others out that you might be more comfortable with.

Re: Quick Regex Question
by Not_a_Number (Prior) on May 07, 2007 at 20:57 UTC

    Your regex is completely wrong. You say that you want MM/DD/YYYY format, and it will match today's date (05/07/2007) but it excludes, for example, 05/23/2007 (not to mention the fact that it's not Y3K compliant :).

    But even if you fixed these problems, how would you deal with eg '02/31/2007' or '39/00/2007'?

    One reason why a lot of people love Perl is CPAN, which, among oodles of other stuff, contains a plethora of modules dealing with dates. My personal favourite is Date::Calc, but YMMV.

    Here's how I'd use the said module to solve your problem:

    use strict; use warnings; use Date::Calc 'check_date'; my $date = '02/31/2007'; # Or whatever my @date = ( split /[-\/]/,$date )[2, 0, 1]; if ( check_date( @date ) ) { # do stuff } else { # print error message }

    Simple, n'est-ce pas?

    Update: Changed value of $date to avoid possible confusion...

Re: Quick Regex Question
by Corion (Patriarch) on May 07, 2007 at 20:12 UTC

    It's hard to say without the values you're testing against. Maybe there is whitespace at the beginning or end of your values or something else.

      My values are just like 03/30/2007 something like that or just DD/MM/YYYY ??? The input is done by me or the user so there is no whitespace.

        A better post would have been then:

        $dated = '03/30/2007'; if ($dated =~ m/^[0-3][0-9]\/[0-1][0-9]\/[1-2][0-9][0-9][0-9]$/) { } else { #User entered an invaild date. $passfail = 0; $errmsg = 'Unable to use date format. Please use "MM/DD/YYYY" or MM-DD +-YYYY for the Date Delivered Field'; $errtitle = 'Validation Error'; $seconds = 7; }

        This fails, because your second segment does only allow for 00 to 19 and never for 30, which seems sensible if you want to validate dates in the format DD/MM/YYYY as you say. Your error message doesn't match that, as there you claim to match MM/DD/YYYY...

        Well.. that is easy... your dates are DD/MM/YYYY bust your regexp is MM/DD/YYYY first section matches 00 to 19, second matches 00 to 39, so many values you pass would fail...
        /^(?:[0-3]\d\/[01]\d\/(?:19|20)\d\d)?$/
        will do it, but as other people have said, there are better ways.

                        - Ant
                        - Some of my best work - (1 2 3)

Re: Quick Regex Question
by Anonymous Monk on May 07, 2007 at 23:19 UTC
    it would be great if we all started using "standard" international date format modules so that (a) the software can run not just in one country (b) you don't need to re-invent the wheel and (c) we can start talking about date related problems from a known starting point (which is not checking that a date is MM/DD/YYYY)
Re: Quick Regex Question
by fenLisesi (Priest) on May 08, 2007 at 09:36 UTC