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

Hi I have the following code for getting the local date. Please let me know if this right because some times users are complaining an error that -1 is not in range so wondering if I have the right code.... $app_date is the date I get from a field value like 2-8-2006 1:14:42 PM
($adate,$atime) = split(/ /, $app_date); ($ayear,$amonth,$aday) = split(/-/, $adate); ($ahour,$amin,$asec) = split(/:/, $atime); $app_time = timelocal($asec, $amin, $ahour, $aday, --$amonth, $ayear);

Replies are listed 'Best First'.
Re: Time local
by BrowserUk (Patriarch) on Dec 21, 2006 at 17:42 UTC

    It sounds like the date field you are getting sometimes does not match the pattern you are expecting.

    For example, if the date was 2/8/2006 1:14:42 PM, then $amonth would be undef and --$amonth would render -1; hence the error message.

    Also, your supplied code snippet is wrong, you are naming the day number as $ayear and the year as $aday.

    You need to verify that the date is in the format you are expecting, and perhaps allow for some alternate formats.

    Maybe something like (untested):

    my $app_time; if( my( $aday, $amonth, $ayear, $ahour, $amin, $asec ) = $appdate =~ m[ (\d{1,2}) [-/] (\d{1,2}) [-/] (\d{4}) \s+ (\d{1,2}) : (\d{1,2}) : (\d{1,2}) ]x ) { $app_time = timelocal( $asec, $amin, $ahour, $aday, --$amonth, $ay +ear ); } else { die "Invalid date (format) '$app_date'"; }

    Or you could look into using one of the many date modules from cpan.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Time local
by kyle (Abbot) on Dec 21, 2006 at 17:43 UTC

    The format for $app_date that you give appears to be month-day-year (or day-month-year—I can't tell which), but your code thinks it's year-month-day. I think your second line down should be:

    ($amonth,$aday,$ayear) = split(/-/, $adate);

    Pulling those fields out of your input might be a little more readable with regular expressions. You could replace all of your split lines with this (unless you need $adate or $atime later):

    ( $amonth, $aday, $ayear, $ahour, $amin, $asec ) = ( $app_date =~ /^(\d\d?)-(\d\d?)-(\d{4}) (1?\d):(\d\d):(\d\d)/ ) +;

    Or this, if you're into xms regexes:

    ( $amonth, $aday, $ayear, $ahour, $amin, $asec ) = ( $app_date =~ m{ \A # beginning of string (\d\d?)-(\d\d?)-(\d{4}) # month-day-year \s # space separator (1?\d):(\d\d):(\d\d) # hour:minutes:seconds }xms );
      I put some debug strings and the date appears as follows: adate is 2007-01-01, atime is 12:00:00 , i had the wrong format before... I will try out the above. Is the --$month right to use?
        I'd use $month-1, since there's no reason to modify $month in the process. The subtraction is required since timelocal expects a 0-based month (Jan = 0).