Re: Leap seconds / time zone bug in DateTime.pm

2004-09-01 Thread Dave Rolsky
On Fri, 6 Aug 2004, Eugene van der Pijll wrote:

 I've attached a patch for the test files. I haven't looked into the
 DateTime.pm code, because both leap second and the time zone handling
 code are just too scary!

I checked this patch in.  I'll try to fix this soon.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Leap seconds / time zone bug in DateTime.pm

2004-08-05 Thread Eugene van der Pijll
There's a bug somewhere in the interaction between leap seconds and time
zones.

In timezones with a positive offset, datetimes after local midnight but
before UTC midnight already are affected by the leap second:

$dt = DateTime-new( year = 1997, month = 7, day = 1,
 hour = 0, minute = 59, second = 59,
 time_zone = '+0100' );
print $dt-iso8601, \n;

# prints 1997-07-01T00:59:60

In timezones with a negative offset it works the other way for datetimes
between UTC midnight and local midnight.

And there's something funny going on with time zones with an offset that
is not an integer number of minutes... e.g.

$dt = DateTime-new( year = 1997, month = 7, day = 1,
 hour = 0, minute = 0, second = 29,
 time_zone = '+00:00:30' );
print $dt-iso8601, \n;

# prints 1997-07-01T23:59:90 !

I've attached a patch for the test files. I haven't looked into the
DateTime.pm code, because both leap second and the time zone handling
code are just too scary!

Eugene


--
Index: t/19leap_second.t
===
RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/t/19leap_second.t,v
retrieving revision 1.22
diff -u -r1.22 19leap_second.t
--- t/19leap_second.t   20 Jul 2004 19:22:26 -  1.22
+++ t/19leap_second.t   6 Aug 2004 01:51:18 -
@@ -2,7 +2,7 @@
 
 use strict;
 
-use Test::More tests = 74;
+use Test::More tests = 78;
 
 use DateTime;
 
@@ -106,7 +106,7 @@
 is( $t-{utc_rd_secs} , 86400, rd_sec );
 }
 
-# test that we can set second to 60
+# test that we can set second to 60 (negative offset)
 {
 my $t = DateTime-new( year = 1972, month = 6, day = 30,
hour = 20, minute = 59, second = 60,
@@ -118,6 +118,43 @@
 
 {
 my $t = DateTime-new( year = 1972, month = 6, day = 30,
+   hour = 21, minute = 0, second = 0,
+   time_zone = 'America/Sao_Paulo',
+ );
+
+is( $t-second, 0, 'datetime just after leap second' );
+}
+
+# test that we can set second to 60 (positive offset)
+{
+my $t = DateTime-new( year = 1972, month = 7, day = 1,
+   hour = 0, minute = 59, second = 60,
+   time_zone = '+0100',
+ );
+
+is( $t-second, 60, 'second set to 60 in constructor' );
+}
+
+{
+my $t = DateTime-new( year = 1972, month = 7, day = 1,
+   hour = 0, minute = 59, second = 59,
+   time_zone = '+0100',
+ );
+
+is( $t-second, 59, 'datetime just before leap second' );
+}
+
+{
+my $t = DateTime-new( year = 1972, month = 7, day = 1,
+   hour = 0, minute = 0, second = 29,
+   time_zone = '+00:00:30',
+ );
+
+is( $t-second, 29, 'time zone +00:00:30' );
+}
+
+{
+my $t = DateTime-new( year = 1972, month = 6, day = 30,
hour = 20, minute = 59, second = 60,
time_zone = 'America/Sao_Paulo',
  );