The 100 years oddity would seem to be related to issue #105031 for Date::Parse:
After str2time uses strptime to break up the incoming date, it passes the result (with $year - 1900) to Time::Local::timelocal. timelocal uses a sliding window to determine if the year should be 19xx or 20xx, completely throwing away the *known* four-digit year that we sent to str2time.
Time::Local interprets the (two digit) date like this:
Years in the range 0..99 are interpreted as shorthand for years in the rolling "current century," defined as 50 years on either side of the current year. Thus, today, in 1999, 0 would refer to 2000, and 45 to 2045, but 55 would refer to 1955. Twenty years from now, 55 would instead refer to 2055. This is messy, but matches the way people currently think about two digit dates.
Years 1968 and 1969 mark the crossover of that window - i.e. 1968 is on one side of 2018 (50 years), and 1969 is on the other (49 years)...
my @dates = ( "1901-01-01 00:00:00", "1968-12-31 23:59:59", "1969-01-01 00:00:00", "1969-12-31 23:59:59", "1970-01-01 00:00:01", ); for my $string (@dates) { my $epoch = str2time( $string, 'GMT' ); print "$string ($epoch seconds)\n"; my $date = DateTime->from_epoch( epoch => $epoch ); print $date->ymd, " ", $date->hms, "\n\n"; }
OUTPUT:
1901-01-01 00:00:00 (978307200 seconds) 2001-01-01 00:00:00 1968-12-31 23:59:59 (3124223999 seconds) 2068-12-31 23:59:59 1969-01-01 00:00:00 (-31536000 seconds) 1969-01-01 00:00:00 1969-12-31 23:59:59 (-1 seconds) 1969-12-31 23:59:59 1970-01-01 00:00:01 (1 seconds) 1970-01-01 00:00:01
 
To verify that the problem is with Date::Parse you can use Time::Local directly to show it returns the correct results if you give it the 4 digit year:
use Time::Local; my %hash = ( "1901-01-01 00:00:00" => [00,00,00,01,00,1901], "1968-12-31 23:59:59" => [59,59,23,31,11,1968], "1969-01-01 00:00:00" => [00,00,00,01,00,1969], "1969-12-31 23:59:59" => [59,59,23,31,11,1969], "1970-01-01 00:00:01" => [01,00,00,01,00,1970], ); for my $string (@dates) { my $array = $hash{$string}; my $epoch = timegm( @$array ); print "$string ($epoch seconds)\n"; my $date = DateTime->from_epoch( epoch => $epoch ); print $date->ymd, " ", $date->hms, "\n\n"; }
OUTPUT:
1901-01-01 00:00:00 (-2177452800 seconds) 1901-01-01 00:00:00 1968-12-31 23:59:59 (-31536001 seconds) 1968-12-31 23:59:59 1969-01-01 00:00:00 (-31536000 seconds) 1969-01-01 00:00:00 1969-12-31 23:59:59 (-1 seconds) 1969-12-31 23:59:59 1970-01-01 00:00:01 (1 seconds) 1970-01-01 00:00:01

In reply to Re: Date::Parse - how to correctly parse dates between 1901 and 1969 by tangent
in thread Date::Parse - how to correctly parse dates between 1901 and 1969 by eniad

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.