atoomic / perl-TimeDate

time & date parsing and formatting perl library
http://search.cpan.org/dist/TimeDate/
1 stars 3 forks source link

After 2018-DEC-31T23:59:59, Date::Parse::str2time returns wrong value for dates before 1970-01-01T00:00:00 [rt.cpan.org #128158] #37

Closed atoomic closed 4 years ago

atoomic commented 4 years ago

Migrated from rt.cpan.org#128158 (status was 'open')

Requestors:

From jeffrey.l.holt@gmail.com on 2019-01-02 22:10:59 :

The str2time 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've tested version 2.30 of TimeDate with ActivePerl 5.20.2.2001,
5.26.3.2603, and 5.28.1 (built from source) on macos. I've also tested
5.26.3.2603 on mswin64 and linux64 with TimeDate 2.30 and gotten the same
incorrect results.

To execute the test, you install perl and TimeDate. Then you execute the
following t.sh, which does 3 things:

1. prints perl path and perl version
2. changes system date to 31-DEC-2018T23:59:59
3. executes a loop printing date and running the t.pl perl script.

Note that I expect t.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.

Here's t.sh:

which perl
perl -v
sudo date 123123592018.58
while [ 1 ]; do
    date
    perl t.pl > t.out 2>&1
    if [ $? -ne 0 ]; then
        cat t.out
        rm t.out
        break
    fi
done

Here's t.pl:

use Date::Parse qw(str2time);
my %tests = (
    "1969-08-16T14:00:00.000000" => "-11854800",
    "1969-08-18T03:00:00.000000" => "-11721600",
    "1969-12-31T23:59:59.999999" => "21599.999999",
    "1970-01-01T00:00:00.000000" => "21600",
);
my $fail = 0;
while (my ($s, $expect) = each %tests) {
    my $got = str2time($s);
    my $result = $expect eq $got ? "OK" : "FAIL";
    print "$result s='$s' expect='$expect' got='$got'\n";
    $fail = 1 if $result ne "OK";
}
exit ($fail ? 1 : 0);

When I execute t.sh, I get the following consistently on my MacBook Pro
running Mojave (10.14.2). Notice that sudo will complain about the local
time being in the future, this should havd no effect on the test outcome:

$ sh t.sh
/usr/local/bin/perl

This is perl 5, version 28, subversion 1 (v5.28.1) built for darwin-2level

Copyright 1987-2018, Larry Wall

Perl may be copied only under the terms of either the Artistic License or
the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
Mon Dec 31 23:59:59 CST 2018
OK s='1970-01-01T00:00:00.000000' expect='21600' got='21600'
FAIL s='1969-12-31T23:59:59.999999' expect='21599.999999' got='3155781600'
FAIL s='1969-08-16T14:00:00.000000' expect='-11854800' got='3143905200'
FAIL s='1969-08-18T03:00:00.000000' expect='-11721600' got='3144038400'

From ether@cpan.org on 2019-01-03 17:47:14 :

Please could you link to the other issue(s) you have opened so that others may track the progress of the fix?

From jeff.holt@method-r.com on 2019-01-03 18:03:37 :

Here's the link to the case I logged with Time::Local.

https://github.com/houseabsolute/Time-Local/issues/8

It turns out that Time::Local has a pod comment implying you (i.e. the Date::Parse maintainer) should never use Time::Local::timelocal.

Instead you should be using timelocal_modern.

Therefore, it's not a bug in Time::Local, it's a "bug" in Date::Parse inasmuch as it hasn't been maintained sufficiently to prevent these types of problems.

I modified the source code to use timelocal_modern but the tests didn't pass.

From blake@vindicia.com on 2019-01-03 20:14:45 :

I don’t think it’s a problem with Time::Local – the real issue is that strptime will subtract 1900 from the yhear number even if you pass in a date with a 4-digit year. Switching to timelocal_modern would completely break str2time for any date after 1900.
This email and the information contained herein is proprietary and confidential and subject to the Amdocs Email Terms of Service, which you may review at https://www.amdocs.com/about/email-terms-of-service <https://www.amdocs.com/about/email-terms-of-service>

From beebop@baz.com on 2019-01-03 20:19:54 :

Whoops, probably shouldn't have sent that from my work email :p

From beebop@baz.com on 2019-01-03 22:40:24 :

Actually upon closer inspection I think there are problems in both
Date::Parse and Time::Local - Date::Parse gives timelocal a 2-digit year
sometimes when it shouldn't be and then timelocal is doing the wrong thing
with it.

>
atoomic commented 4 years ago

This is going to be fixed by 4b67ccbdc1846620470ca524a5f3e2afd7b33f66