Closed jlholt closed 5 years ago
You're being bitten by this - https://metacpan.org/pod/Time::Local#Year-Value-Interpretation
Use timelocal_modern
and timegm_modern
and pass them 4 digit years to avoid this madness.
I'm actually logging this bug as a courtesy to Graham Barr, whose Date::Parse uses your Time::Local::timelocal function. Can you contact him about fixing his code? I logged bug 128158 but when I thought I found the source of the problem (your module), I sent an email asking for 128158 to be closed. That was a mistake given your feedback but I failed miserably when I tried to add an update for the bug. The rt site is a disgrace.
I doubt that Date::Parse
can be changed either. It's an old module with lots of legacy code relying on its current behavior. I'd suggest using something like DateTime or Time::Moment.
I'd love to use something else but I need something that parses dates, especially ISO 8601 date time values like the ones mentioned in the title of this case.
Perhaps DateTime::Format::ISO8601 is all I need for parsing such dates?
That would probably work. If not, DateTime::Format::Natural will parse many many formats.
DateTime::Format::Natural does not handle ISO 8601 "Combined date and time representations".
$ cat t.pl use DateTime::Format::Natural;
my $s1 = "1999-01-01T00:00:00"; my $dtparser = DateTime::Format::Natural->new(); my $dt = $dtparser->parse_datetime($s1); die $dtparser->error if ! $dtparser->success;
$ perl t.pl '1999-01-01T00:00:00' does not parse (perhaps you have some garbage?) at t.pl line 6.
But it's not that big of deal to first try DateTime::Format::ISO8601 and fall back upon DateTime::Format::Natural if necessary.
The timelocal function returns the wrong value as soon as the system clock reaches 01-JAN-2019T00:00:00.000000. But it apparently only does so for time values that precede 01-JAN-1970T00:00:00.000000.
I'm using Time::Local v1.28 on Perl v5.28.1 (built from source) on macos v10.14.2.
To execute the test, you install perl and Time::Local. Then you execute the following tl.sh, which does 3 things:
Note that I expect tl.pl to exit with 1 as I stated above. If you cannot reproduce the failure, then you'll have to interrupt the execution once it becomes clear you won't reproduce the results. Also note that the only reason I've created this particular test is to show when in time the test starts to fail. Obviously, it will always fail for these old dates now that the clock is into 2019 but I thought it important for the module's author to know when in time it started to fail.
This is tl.sh:
which perl perl -V:version sudo date 123123592018.57 while [ 1 ]; do date perl tl.pl > t.out 2>&1 if [ $? -ne 0 ]; then cat t.out rm t.out break fi done
This is tl.pl:
use Time::Local;
my @tests = ( {name=>"1969-08-16T14:00:00", expect=>"-11854800", tlargs=>['00', '00', 14, '16', 07, 69, undef]}, {name=>"1969-08-18T03:00:00", expect=>"-11721600", tlargs=>['00', '00', 03, '18', 07, 69, undef]}, {name=>"1969-12-31T23:59:59", expect=>"21599", tlargs=>['59', '59', 23, '31', 11, 69, undef]}, {name=>"1970-01-01T00:00:00", expect=>"21600", tlargs=>['00', '00', 00, '01', 00, 70, undef]}, ); my $fail = 0; for (@tests) { my $test = $->{name}; my $expect = $->{expect}; my $got = timelocal(@{$_->{tlargs}}); my $result = $expect eq $got ? "OK" : "FAIL"; print "$test: $result expect='$expect' got='$got'\n"; $fail = 1 if $result ne "OK"; } exit ($fail ? 1 : 0);
When I execute tl.sh (after resetting the clock to the current date&time), I get the following consistently on my MacBook Pro running Mojave (10.14.2):
$ sh tl.sh /usr/local/bin/perl version='5.28.1'; Mon Dec 31 23:59:57 CST 2018 Mon Dec 31 23:59:57 CST 2018 ... lines elided Mon Dec 31 23:59:58 CST 2018 Mon Dec 31 23:59:58 CST 2018 ... lines elided Mon Dec 31 23:59:59 CST 2018 Mon Dec 31 23:59:59 CST 2018 ... lines elided Mon Dec 31 23:59:59 CST 2018 Tue Jan 1 00:00:00 CST 2019 1969-08-16T14:00:00: FAIL expect='-11854800' got='3143905200' 1969-08-18T03:00:00: FAIL expect='-11721600' got='3144038400' 1969-12-31T23:59:59: FAIL expect='21599' got='3155781599' 1970-01-01T00:00:00: OK expect='21600' got='21600'