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

I am currently checking for valid dates by using the Date::Manip package, e.g.

unless (&ParseDate("02/31/2000")){
     print "Bad Date!";
}

It is hard for me to believe that perl would not have a built-in isvalid operator to test for the validity of dates, but the llama book doesn't mention one and neither does my google search.

I hate to require my users to install Date::Manip. Is there some better way to check the validity of dates? I am writing a CGI application, so if there was some way for CGI.pm to test the validity of dates then that would be great.

I am also curious why there is an ampersand in &parsedate. I was not aware that variable or function names can begin with an ampersand.

Replies are listed 'Best First'.
Re: Checking for Valid Dates
by danger (Priest) on Jan 04, 2001 at 03:53 UTC
    It is hard for me to believe that perl would not have a built-in isvalid operator to test for the validity of dates, but the llama book doesn't mention one and neither does my google search.

    You are correct: Perl does not have an is_valid operator or function for dates, and such a thing does not belong in the language (IMHO), but in a library (like Date::Manip or Date::Calc), or even in the standard Time::Local module (which doesn't have a simple is_valid function, but you could create one with it). Also, Date::Manip is rather slow, the author of it even suggest that 90% of the time you probably want to use one of the other date/time modules -- you might consider using Date::Calc instead.

    I am also curious why there is an ampersand in &parsedate. I was not aware that variable or function names can begin with an ampersand.

    The ampersand is largely a holdover from perl4 times when that was how you invoked a subroutine (just like scalars, arrays, and hashes had their own type specifier, so did subroutines). There are a few differences when ampersand is used compared to when it is not used:

    &func; # calls func with current contents of @_ # no prototype checking &func() # calls func with no args, no prototype checking

    see the perlsub manpage for more details.

      Altough the ampersand is not mandatory, I use it, in order to read my code easier. In my opinion it belongs to the structured perl programming style.

      -- tune

        Altough the ampersand is not mandatory, I use it, in order to read my code easier. In my opinion it belongs to the structured perl programming style.

        I would disagree. I think it is clumsy, confusing, needless and potentially problematic:

        From perlfaq7:

        What's the difference between calling a function as &foo and foo()?

        When you call a function as `&foo', you allow that
        function access to your current @_ values, and you by-pass
        prototypes.  That means that the function doesn't get an
        empty @_, it gets yours!  While not strictly speaking a
        bug (it's documented that way in the perlsub manpage), it
        would be hard to consider this a feature in most cases.
        
        When you call your function as `&foo()', then you do get a
        new @_, but prototyping is still circumvented.
        
        Normally, you want to call a function using `foo()'.  You
        may only omit the parentheses if the function is already
        known to the compiler because it already saw the
        definition (`use' but not `require'), or via a forward
        reference or `use subs' declaration.  Even in this case,
        you get a clean @_ without any of the old values leaking
        through where they don't belong.

        Tony

Re: Checking for Valid Dates
by tune (Curate) on Jan 04, 2001 at 03:08 UTC
    Time::Local is good for this purpose too. Its timelocal() function will give a -1 if the given date is invalid. This module is more common than Date::Manip, since it is installed by default

    -- tune

Re: Checking for Valid Dates
by footpad (Abbot) on Jan 04, 2001 at 03:24 UTC
    I am also curious why there is an ampersand in &parsedate. I was not aware that variable or function names can begin with an ampersand.

    From perlman:perlsub:

    To call subroutines: NAME(LIST); # & is optional with parentheses. NAME LIST; # Parentheses optional if predeclared/imported. &NAME; # Makes current @_ visible to called subroutine.

    --f