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

Hello there Monks,

For some reason when I pass timelocal() the number 8 for months which is August and the day is 31, it gives me this error.

Day '31' out of range 1..30 at ./myFile.pl line 147

I can post all the code if necessary but I've checked all the variables and it's definitely getting the correct values.


Below is a snippet from my code that is having the issue.

For the code below the 2D array has this data in it. Each element is separated by whitespace

OWNER /ud/QC-DATA/CONTROL 001!SCHEDULE X 3462970 9223372195768565774 userMike 5005444 156 pts/220 11:00:44 Aug 31
WAITING /ud/QC-DATA/CONTROL 001!SCHEDULE X 3462970 9223372195768565774 UserJoe 3309650 35 none 11:03:44 Aug 31

my %months = ('Jan'=>1, 'Feb'=>2, 'Mar'=>3, 'Apr'=>4, 'May'=>5, 'Jun'=>6, 'Jul'=>7, 'Aug'=>8, 'Sep'=>9, 'Oct'=>10, 'Nov'=>11, 'Dec'=>12 ); calcTime(); sub calcTime { # These will hold the 'timelocal' for the current OWNER and curren +t WAITER being processed. my $ownTime; my $waitTime; # Loop through all the records and calculate time diff between an +'OWNER' and any 'WAITING' users up until the next 'OWNER'. for (my $x = 0; $x <= $#records; $x++) { #If the current line at the first elemnt is equal to 'OWNER' t +hen... if ($AoA[$x][0] eq 'OWNER') { for (my $y = $x+1; $y <= $#records; $y++) { if ($AoA[$x][0] ne $AoA[$y][0] && $AoA[$x][2] eq $AoA[ +$y][2] && !(exists $AoA[$y][13])) { #Splits field containg the 'TIME' into 3 seperate +variables (hours, minutes, seconds) my ($ohour, $omin, $osec) = split ':', $AoA[$x][10 +]; my ($whour, $wmin, $wsec) = split ':', $AoA[$y][10 +]; for (my $i = 0; $i <= $#records; $i++) { for (my $j = 0; $j <= 13; $j++) { print "$j. $AoA[$i][$j]\n"; } } #********************************* Getting error below from $ownT +ime, when using $AoA[$x][12] instead of $AoA[$x][10] **************** +************* #Convert into time $ownTime=timelocal($osec, $omin, $ohour, , $AoA[$x +][12], $months{ $AoA[$x][11] }, $year); $waitTime=timelocal($wsec, $wmin, $whour, , $AoA[$ +x+1][12], $months{ $AoA[$x+1][11] }, $year); #Calculate time difference between. my $timeDiff = $waitTime-$ownTime; $timeDiff = $timeDiff/60; $timeDiff = sprintf '%.1f minutes', $timeDiff; #Add the time difference to the end of the 'WAITER +S' line in @AoA and print it out. $AoA[$y][13] = $timeDiff; } #END IF } #END FOR-->$y } #END IF } #END FOR-->$x }




Any suggestions are much appreciated.


Thanks,
Matt

Replies are listed 'Best First'.
Re: Error while using "timelocal ()" function.
by choroba (Cardinal) on Aug 31, 2011 at 21:00 UTC
    Aren't months zero-based (i.e. 0 = January, 8 = September)?
      Correct: "the month is the number of months since January (0..11). This is consistent with the values returned from localtime() and gmtime()"
      Thanks for the replies.

      I did not think of that (months being zero-based). I'll change it up and see what happens.


      I'll post back as soon as I give it a try.


      Thanks, Matt
Re: Error while using "timelocal ()" function.
by toolic (Bishop) on Aug 31, 2011 at 21:08 UTC
    According to the documentation (perldoc Time::Local):
    the month is the number of months since January (0..11).
    Therefore, August should be 7, not 8.
    I can post all the code if necessary
    Just the opposite: you should reduce your code to the smallest number of lines possible to reproduce the problem.
    #!/usr/bin/env perl use warnings; use strict; use Time::Local; timelocal(0,0,0,31,8,2011); __END__ Day '31' out of range 1..30 at ./923524.pl line 7
      Thanks for the info, good to know.

      Thanks,
      Matt
Re: Error while using "timelocal ()" function.
by ikegami (Patriarch) on Aug 31, 2011 at 21:14 UTC
    Alternative:
    use strict; use warnings; use feature qw( say ); use DateTime::Format::Strptime qw( ); my $strp = DateTime::Format::Strptime->new( pattern => "%T %b %d %Y", locale => "en", time_zone => "local", on_error => "croak", ); my $year = "2011"; my $ownTime = $strp->parse_datetime("11:00:44 Aug 31"." ".$year); my $waitTime = $strp->parse_datetime("11:03:44 Aug 31"." ".$year); my $dur = $waitTime->delta_ms($ownTime); say $dur->minutes();

    DateTime::Format::Strptime, DateTime, DateTime::Duration

Re: Error while using "timelocal ()" function.
by mmartin (Monk) on Sep 01, 2011 at 20:18 UTC

    Hey Guys,

    Just got a chance to modify my code. Thanks again, it worked great!
    It's funny, it always seems that it's the little easy things that give the most trouble haha...


    Thanks Again, Matt
      It's a common mistake that goes to show that interfaces should be designed for people, not computers.
      What was the issue with timelocal()?
      Can you please share your solution?

      I am getting the same error(Day '' out of range 1..31 script.pl at line2 ), but finding to hard to find the solution?

      Code snippet:

      use Time::Local; my $time = timegm( $sec, $min, $hours, $mday, $mon, $year );
      Thanks.

        Have you looked at what value you are passing to timegm()?

        Most likely, $mday is empty for some reason, as the error message tells you.