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

Hi, I was under the impression, that timelocal_nocheck can be used with values for month and day larger than days in a month or month in a year, but it works only for days.

I expect the following output:
Sat Jan 1 00:00:00 2005 Sun Jan 1 00:00:00 2006
but I get this.
use Time::Local qw/timelocal_nocheck/; print scalar( localtime( timelocal_nocheck( 0,0,0,1,0,5 )) ), "\n"; print scalar( localtime( timelocal_nocheck( 0,0,0,1,12,5 )) ); __OUTPUT__ Sat Jan 1 00:00:00 2005 Sat Jan 1 00:00:00 2005
Boris

Replies are listed 'Best First'.
Re: timelocal_nocheck: bug or wrongly understood
by blokhead (Monsignor) on Nov 28, 2005 at 17:30 UTC
    The pod says (emphasis added):
    # The 365th day of 1999 print scalar localtime timelocal_nocheck 0,0,0,365,0,99; # The twenty thousandth day since 1970 print scalar localtime timelocal_nocheck 0,0,0,20000,0,70; # And even the 10,000,000th second since 1999! print scalar localtime timelocal_nocheck 10000000,0,0,1,0,99;
    Your mileage may vary when trying these with minutes and hours, and it doesn't work at all for months.
    I wonder if there is a technical reason for this. Perhaps it's because months aren't the same size, while days, hours, minutes, and seconds are almost always the same size. Even so, its current behavior still seems strange.. at least it could try to do something reasonable with months > 12 instead of reducing mod 12 as it does now.

    blokhead

Re: timelocal_nocheck: bug or wrongly understood
by ikegami (Patriarch) on Nov 28, 2005 at 19:06 UTC

    The bug is easily fixable. Change:

    sub _daygm { $_[3] + ($Cheat{pack("ss",@_[4,5])} ||= do { my $month = ($_[4] + 10) % 12; my $year = $_[5] + 1900 - $month/10; 365*$year + $year/4 - $year/100 + $year/400 + ($month*306 + 5)/10 +- $Epoc }); }

    to

    sub _daygm { $_[3] + ($Cheat{pack("ss",@_[4,5])} ||= do { my $month = ($_[4] + 10) % 12; my $year = $_[5] + 1900 + ($_[4] + 10) / 12 - 1; 365*$year + $year/4 - $year/100 + $year/400 + ($month*306 + 5)/10 +- $Epoc }); }

    My test:

    I created a ticket.

Re: timelocal_nocheck: bug or wrongly understood
by ikegami (Patriarch) on Nov 28, 2005 at 18:34 UTC

    Interestingly, older versions give:

    Sat Jan 1 00:00:00 2005 Can't handle date (0, 0, 0, 1, 12, 105) at script.pl line 3

    This is with the Time::Local that came with Perl 5.6.1. No version is specified in the .pm.

Re: timelocal_nocheck: bug or wrongly understood
by gu (Beadle) on Nov 28, 2005 at 19:00 UTC
    At first glance I don't see why something like
    if ($month > 11) { my $gap = int($month/12) ; $year += $gap ; $month -= 12*$gap ; }
    out of the unless ($Options{no_range_check}) braces in Local.pm timegm function shouldn't make it, at least for months over 11... For negative months it's a bit more complex...

    Gu
Re: timelocal_nocheck: bug or wrongly understood
by borisz (Canon) on Nov 29, 2005 at 08:57 UTC
    Thanks all,
    until this is fixed, I use POSIX::mktime, where large months are permitted.
    Boris