diff --git a/lib/Date/Parse.pm b/lib/Date/Parse.pm index c07ae2b..9512d15 100644 --- a/lib/Date/Parse.pm +++ b/lib/Date/Parse.pm @@ -73,7 +73,7 @@ sub { my $dtstr = lc shift; my $merid = 24; - my($year,$month,$day,$hh,$mm,$ss,$zone,$dst,$frac); + my($century,$year,$month,$day,$hh,$mm,$ss,$zone,$dst,$frac); $zone = tz_offset(shift) if @_; @@ -195,12 +195,15 @@ sub { } } - $year -= 1900 if defined $year && $year > 1900; + if (defined $year && $year > 1900) { + $century = int($year / 100); + $year -= 1900; + } $zone += 3600 if defined $zone && $dst; $ss += "0.$frac" if $frac; - return ($ss,$mm,$hh,$day,$month,$year,$zone); + return ($ss,$mm,$hh,$day,$month,$year,$zone,$century); } ESQ @@ -233,7 +236,7 @@ sub str2time return undef unless @t; - my($ss,$mm,$hh,$day,$month,$year,$zone) = @t; + my($ss,$mm,$hh,$day,$month,$year,$zone, $century) = @t; my @lt = localtime(time); $hh ||= 0; @@ -252,6 +255,9 @@ sub str2time $year = ($month > $lt[4]) ? ($lt[5] - 1) : $lt[5] unless(defined $year); + # we were given a 4 digit year, so let's keep using those + $year += 1900 if defined $century; + return undef unless($month <= 11 && $day >= 1 && $day <= 31 && $hh <= 23 && $mm <= 59 && $ss <= 59); @@ -317,9 +323,9 @@ date string does not specify a timezone. =item strptime(DATE [, ZONE]) C takes the same arguments as str2time but returns an array of -values C<($ss,$mm,$hh,$day,$month,$year,$zone)>. Elements are only defined -if they could be extracted from the date string. The C<$zone> element is -the timezone offset in seconds from GMT. An empty array is returned upon +values C<($ss,$mm,$hh,$day,$month,$year,$zone,$century)>. Elements are only +defined if they could be extracted from the date string. The C<$zone> element +is the timezone offset in seconds from GMT. An empty array is returned upon failure. =back diff --git a/t/cpanrt.t b/t/cpanrt.t index 32b37e7..8ffd9fa 100644 --- a/t/cpanrt.t +++ b/t/cpanrt.t @@ -1,7 +1,7 @@ use Date::Format qw(time2str strftime); use Date::Parse qw(strptime str2time); -print "1..8\n"; +print "1..9\n"; my $i = 1; @@ -22,7 +22,7 @@ my $i = 1; my @t = strptime($str); my $t = join ":", map { defined($_) ? $_ : "-" } @t; print "# $str => $t\n"; - print "not " unless $t eq "-:35:22:30:10:108:3600"; + print "not " unless $t eq "-:35:22:30:10:108:3600:20"; print "ok ", $i++, "\n"; } } @@ -53,3 +53,13 @@ my $i = 1; print "not " if str2time('16 Oct 09') < 0; print "ok ", $i++, "\n"; } + +{ # RT#84075: Date::Parse::str2time maps date in 1963 to 2063 + my $this_year = 1900 + (gmtime(time))[5]; + my $target_year = $this_year - 50; + my $date = "$target_year-01-01 00:00:00 UTC"; + my $time = str2time($date); + my $year_parsed_as = 1900 + (gmtime($time))[5]; + print "not " unless $year_parsed_as == $target_year; + print "ok ", $i++, "\n"; +}