DateTime::Format::Strptime version 0.0702 (and earlier) fails to
set the day, minute, and second when parsing from an epoch seconds
value (%s).

The returned DateTime object is also in the floating time zone, which
means that setting a new time zone on the object causes the datetime
value to be incorrect.

Attached is a patch which tests for these conditions and provides
fixes in the module.

-kolibrie

Thu Sep 27 16:34:14 EDT 2007  [EMAIL PROTECTED]
  * epoch seconds are tied to UTC rather than floating time zone
diff -rN -u old-DateTime-Format-Strptime/lib/DateTime/Format/Strptime.pm new-DateTime-Format-Strptime/lib/DateTime/Format/Strptime.pm
--- old-DateTime-Format-Strptime/lib/DateTime/Format/Strptime.pm	2007-09-27 16:37:14.000000000 -0400
+++ new-DateTime-Format-Strptime/lib/DateTime/Format/Strptime.pm	2007-09-27 16:37:14.000000000 -0400
@@ -343,7 +343,7 @@
 
 	# If there's an epoch, we're done. Just need to check all the others
 	if ($epoch) {
-		$epoch_dt = DateTime->from_epoch( epoch => $epoch, time_zone => $use_timezone );
+		$epoch_dt = DateTime->from_epoch( epoch => $epoch, time_zone => (ref($use_timezone) and $use_timezone->name eq 'floating') ? 'UTC' : $use_timezone );
 
 		$Year      = $epoch_dt->year;
 		$Month     = $epoch_dt->month;
@@ -438,7 +438,7 @@
 		? $day
 		: ($doy_dt)
 			? $doy_dt->day
-			: '';
+			: $Day;
 	if ($Day) {
 		$self->local_croak("There is no use providing a day without providing a month and year.") and return undef unless $Year and $Month;
 		my $dt = DateTime->new(year=>$Year, month=>$Month, day=>$Day, hour=>12, time_zone => $use_timezone);
@@ -476,15 +476,19 @@
 	print "Set hour to $Hour.\n" if $self->{diagnostic};
 
 	# Minutes
-	$self->local_croak("$minute is too large to be a minute.") and return undef unless $minute <= 59;
-	$Minute = $minute;
+	if (length($minute)) {
+		$self->local_croak("$minute is too large to be a minute.") and return undef unless $minute <= 59;
+		$Minute = $minute;
+	}
 	$self->local_croak("Your minute does not match your epoch.") and return undef if $epoch_dt and $Minute and $Minute != $epoch_dt->minute;
 	print "Set minute to $Minute.\n" if $self->{diagnostic};
 
 
 	# Seconds
-	$self->local_croak("$second is too large to be a second.") and return undef unless $second <= 59; #OK so leap seconds will break!
-	$Second = $second;
+	if (length($second)) {
+		$self->local_croak("$second is too large to be a second.") and return undef unless $second <= 59; #OK so leap seconds will break!
+		$Second = $second;
+	}
 	$self->local_croak("Your second does not match your epoch.") and return undef if $epoch_dt and $Second and $Second != $epoch_dt->second;
 	print "Set second to $Second.\n" if $self->{diagnostic};
 
@@ -508,7 +512,7 @@
     	nanosecond	=> ($Nanosecond || 0),
 
     	locale      =>	$self->{_locale},
-    	time_zone	=>	$use_timezone,
+    	time_zone	=>	($epoch and ref($use_timezone) and $use_timezone->name eq 'floating') ? DateTime::TimeZone->new( name => 'UTC' ) : $use_timezone,
 	);
 
 	$self->local_croak("Your day of the week ($dow_mon_1) does not match the date supplied: ".$potential_return->ymd) and return undef if $dow_mon_1 and $potential_return->dow != $dow_mon_1;
diff -rN -u old-DateTime-Format-Strptime/t/007_edge.t new-DateTime-Format-Strptime/t/007_edge.t
--- old-DateTime-Format-Strptime/t/007_edge.t	2007-09-27 16:37:14.000000000 -0400
+++ new-DateTime-Format-Strptime/t/007_edge.t	2007-09-27 16:37:14.000000000 -0400
@@ -2,7 +2,7 @@
 
 # t/007_edge.t - these tests are for edge case bug report errors
 
-use Test::More tests => 15;
+use Test::More tests => 20;
 use DateTime;
 use DateTime::Format::Strptime;
 
@@ -29,6 +29,21 @@
 	is($parsed->time_zone->name,'floating');
 }
 
+# epoch seconds are tied to UTC, not floating timezone
+{
+	my $parser = DateTime::Format::Strptime->new(
+		pattern   => '%s',
+		on_error  => 'undef',
+                diagnostic => 1,
+	);
+	isa_ok($parser, 'DateTime::Format::Strptime');
+	my $parsed = $parser->parse_datetime('1103059515');
+	isa_ok($parsed, 'DateTime');
+	is($parsed->datetime,'2004-12-14T21:25:15', 'Date and time are correct');
+	is($parsed->epoch,'1103059515', 'epoch seconds matches parsed string');
+	is($parsed->time_zone->name,'UTC','Time zone is UTC');
+}
+
 
 #diag("1.0601 - Olson Time Zones - %O");
 {

Attachment: signature.asc
Description: Digital signature

Reply via email to