Skip Menu |

This queue is for tickets about the Time-modules CPAN distribution.

Report information
The Basics
Id: 70130
Status: new
Priority: 0/
Queue: Time-modules

People
Owner: Nobody in particular
Requestors: schobes [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Inconsistent parsedate() handling of invalid date / times during DST
When using parsedate() on invalid date time during DST the expected behavior is not working as it does in other circumstances. This problem only presents itself during the spring ahead event. Example: Show quoted text
> TZ=US/Eastern perl -e 'use Time::ParseDate; print parsedate("2011-03-
13 02:30:00")."\n";' 1299997800 Show quoted text
> TZ=US/Eastern perl -e 'use Time::CTime; print strftime("%Y-%m-%d
%H:%M:%S", localtime(1299997800))."\n";' 2011-03-13 01:30:00 The reason I am stating this is inconsistent with parsedate's behavior is based upon what parsedate does with other invalid date times. Example: February 31st Show quoted text
> TZ=US/Eastern perl -e 'use Time::ParseDate; print parsedate("2011-02-
31 00:00:00")."\n";' 1299128400 Show quoted text
> TZ=US/Eastern perl -e 'use Time::CTime; print strftime("%Y-%m-%d
%H:%M:%S", localtime(1299128400))."\n";' 2011-03-03 00:00:00 Example: 30:00:00 Show quoted text
> TZ=US/Eastern perl -e 'use Time::ParseDate; print parsedate("2011-01-
01 30:00:00")."\n";' 1293966000 Show quoted text
> TZ=US/Eastern perl -e 'use Time::CTime; print strftime("%Y-%m-%d
%H:%M:%S", localtime(1293966000))."\n";' 2011-01-02 06:00:00 During DST spring forward event, parsedate() of invalid datetime results in a unix timestamp that is in the past instead of in the future. I have attached a patch so that parsedate's handling of this DST event becomes consistent with the rest of the parsedate's handling of invalid date times.
Subject: parsedate.diff
diff --git a/lib/Time/ParseDate.pm b/lib/Time/ParseDate.pm index c46b732..fb2693a 100644 --- a/lib/Time/ParseDate.pm +++ b/lib/Time/ParseDate.pm @@ -371,7 +371,7 @@ sub parsedate unless ($options{GMT}) { if ($options{ZONE}) { $tzadj = tz_offset($options{ZONE}, $secs) || 0; - $tzadj = tz_offset($options{ZONE}, $secs-$tzadj); + my $tzadj2 = tz_offset($options{ZONE}, $secs-$tzadj); unless (defined($tzadj)) { return (undef, "could not convert '$options{ZONE}' to time offset") if wantarray(); @@ -380,14 +380,42 @@ sub parsedate print "adjusting secs for $options{ZONE}: $tzadj\n" if $debug; $secs -= $tzadj; } else { - $tzadj = tz_local_offset($secs); + my $tzadj = tz_local_offset($secs); print "adjusting secs for local offset: $tzadj\n" if $debug; # # Just in case we are very close to a time # change... # - $tzadj = tz_local_offset($secs-$tzadj); - $secs -= $tzadj; + my $tzadj2 = tz_local_offset($secs-$tzadj); + + # + # To provide consistent handling of invalid + # times, this forces the time forward when + # provided a date / time within the + # perceived spring forward event of DST + # (example: from EST to EDT parsedate('02:30:00') + # does not exist but turns to '01:30:00', + # instead of going to 03:30:00, similar to + # the behavior of parsedate('2011-02-31') which + # would be 2011-03-03). + # + my $use_original_offset = 0; + if ($tzadj2 > $tzadj) { + for (my $i = $secs - $tzadj; $i >= $secs - $tzadj2; $i--) { + my $t_tzadj = tz_local_offset($i); + ## it changed in here some where. + if ($t_tzadj == $tzadj) { + $use_original_offset = 1; + last; + } + } + } + + if ($use_original_offset) { + $secs -= $tzadj; + } else { + $secs -= $tzadj2; + } } } } diff --git a/t/datetime.t b/t/datetime.t index 416ebc8..568dc58 100755 --- a/t/datetime.t +++ b/t/datetime.t @@ -310,6 +310,8 @@ BEGIN { 1012550400, ['2/1/02', NOW => 1011252345, FUZZY => 1, PREFER_FUTURE => 1], 1011247200, ['6am', GMT => 1, NOW => 1011252345], 1256435700, ['2009-10-25 02:55:00', ZONE => 'MEZ'], + 1300001400, ['2011-03-13 02:30:00', ZONE => 'EST'], + 1301189400, ['2011-03-27 03:30:00', ZONE => 'EET'], ); %tztests = ( @@ -494,3 +496,26 @@ while (@sdt) { } $c++; } + +# handling of spring foward events, invalid times. + +$ENV{TZ} = 'US/Eastern'; +tzset; +if (parsedate('2011-03-13 02:30:00') == 1300001400) { + $c++; + print "ok $c # US/Eastern spring ahead event, invalid time\n"; +} else { + $c++; + print "not ok $c # US/Eastern spring ahead event, invalid time\n"; +} + +$ENV{TZ} = 'Europe/Athens'; +tzset; +if (parsedate('2011-03-27 03:30:00') == 1301189400) { + $c++; + print "ok $c # Europe/Athens spring ahead event, invalid time\n"; +} else { + $c++; + print "not ok $c # Europe/Athens spring ahead event, invalid time\n"; +} +
Subject: Re: [rt.cpan.org #70130] AutoReply: Inconsistent parsedate() handling of invalid date / times during DST
Date: Thu, 1 Sep 2011 08:11:17 -0400
To: bug-Time-modules [...] rt.cpan.org
From: Adam Schobelock <schobes [...] gmail.com>
Here is another patch that is less complicated and resolves the reported issue. On Mon, Aug 8, 2011 at 7:29 AM, Bugs in Time-modules via RT < bug-Time-modules@rt.cpan.org> wrote: Show quoted text
> > Greetings, > > This message has been automatically generated in response to the > creation of a trouble ticket regarding: > "Inconsistent parsedate() handling of invalid date / times during > DST", > a summary of which appears below. > > There is no need to reply to this message right now. Your ticket has been > assigned an ID of [rt.cpan.org #70130]. Your ticket is accessible > on the web at: > > https://rt.cpan.org/Ticket/Display.html?id=70130 > > Please include the string: > > [rt.cpan.org #70130] > > in the subject line of all future correspondence about this issue. To do > so, > you may reply to this message. > > Thank you, > bug-Time-modules@rt.cpan.org > > ------------------------------------------------------------------------- > When using parsedate() on invalid date time during DST the expected > behavior is not working as it does in other circumstances. This problem > only presents itself during the spring ahead event. > > Example: >
> > TZ=US/Eastern perl -e 'use Time::ParseDate; print parsedate("2011-03-
> 13 02:30:00")."\n";' > 1299997800 >
> > TZ=US/Eastern perl -e 'use Time::CTime; print strftime("%Y-%m-%d
> %H:%M:%S", localtime(1299997800))."\n";' > 2011-03-13 01:30:00 > > The reason I am stating this is inconsistent with parsedate's behavior > is based upon what parsedate does with other invalid date times. > > Example: February 31st >
> > TZ=US/Eastern perl -e 'use Time::ParseDate; print parsedate("2011-02-
> 31 00:00:00")."\n";' > 1299128400 >
> > TZ=US/Eastern perl -e 'use Time::CTime; print strftime("%Y-%m-%d
> %H:%M:%S", localtime(1299128400))."\n";' > 2011-03-03 00:00:00 > > Example: 30:00:00 >
> > TZ=US/Eastern perl -e 'use Time::ParseDate; print parsedate("2011-01-
> 01 30:00:00")."\n";' > 1293966000 >
> > TZ=US/Eastern perl -e 'use Time::CTime; print strftime("%Y-%m-%d
> %H:%M:%S", localtime(1293966000))."\n";' > 2011-01-02 06:00:00 > > During DST spring forward event, parsedate() of invalid datetime results > in a unix timestamp that is in the past instead of in the future. I > have attached a patch so that parsedate's handling of this DST event > becomes consistent with the rest of the parsedate's handling of invalid > date times. >

Message body is not shown because sender requested not to inline it.