Hi Folks,

DateTime::LeapSecond claims that there have been 23 leap-seconds since the start of 
UTC.  This is _incorrect_.  There have been only 22 leap-seconds in the history of 
UTC.  This error is introduced on be the addition of a leap-second on 1972-01-01.  
That is the date when the delta been UTC-TAI is defined to be exactly +10 but no 
leap-second occurred.

A possible patch to correct this is attached.  Are there any objections to this being 
committed?  This could potentially break existing code but only because the current 
behavior is broken.

Cheers,

-J

--
? DateTime.bs
? DateTime.c
? Makefile
? blib
? dt_leapsecond.diff
? leap_seconds.h
? pm_to_blib
? t/zz_00load.t
? t/zz_01sanity.t
? t/zz_02last_day.t
? t/zz_03components.t
? t/zz_04epoch.t
? t/zz_05set.t
? t/zz_06add.t
? t/zz_07compare.t
? t/zz_09greg.t
? t/zz_10subtract.t
? t/zz_11duration.t
? t/zz_12week.t
? t/zz_13strftime.t
? t/zz_14locale.t
? t/zz_15jd.t
? t/zz_16truncate.t
? t/zz_17set_return.t
? t/zz_18today.t
? t/zz_19leap_second.t
? t/zz_20infinite.t
? t/zz_21bad_params.t
? t/zz_22from_doy.t
? t/zz_23storable.t
? t/zz_24from_object.t
? t/zz_25add_subtract.t
? t/zz_27delta.t
? t/zz_28dow.t
? t/zz_29overload.t
? t/zz_30future_tz.t
Index: leaptab.txt
===================================================================
RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/leaptab.txt,v
retrieving revision 1.1
diff -u -r1.1 leaptab.txt
--- leaptab.txt 6 Aug 2003 14:09:26 -0000       1.1
+++ leaptab.txt 19 Jul 2004 02:23:33 -0000
@@ -1,4 +1,3 @@
-1972  Jan. 1  +1
 1972  Jul. 1  +1
 1973  Jan. 1  +1
 1974  Jan. 1  +1
Index: lib/DateTime/LeapSecond.pm
===================================================================
RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/lib/DateTime/LeapSecond.pm,v
retrieving revision 1.7
diff -u -r1.7 LeapSecond.pm
--- lib/DateTime/LeapSecond.pm  2 Dec 2003 05:09:48 -0000       1.7
+++ lib/DateTime/LeapSecond.pm  19 Jul 2004 02:23:33 -0000
@@ -83,7 +83,6 @@
     # year month day number-of-leapseconds
     #
     _init ( qw(
-1972  Jan. 1  +1 
 1972  Jul. 1  +1
 1973  Jan. 1  +1
 1974  Jan. 1  +1
@@ -143,7 +142,7 @@
 =item * leap_seconds( $rd )
 
 Returns the number of accumulated leap seconds for a given day,
-in the range 0 .. 23.
+in the range 0 .. 22.
 
 =item * extra_seconds( $rd )
 
Index: t/19leap_second.t
===================================================================
RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/t/19leap_second.t,v
retrieving revision 1.21
diff -u -r1.21 19leap_second.t
--- t/19leap_second.t   10 Feb 2004 15:57:50 -0000      1.21
+++ t/19leap_second.t   19 Jul 2004 02:23:33 -0000
@@ -9,35 +9,35 @@
 
 # tests using UTC times
 {
-    # 1971-12-31T23:58:20 UTC
-    my $t = DateTime->new( year => 1971, month => 12, day => 31,
+    # 1972-06-30T23:58:20 UTC
+    my $t = DateTime->new( year => 1972, month => 6, day => 30,
                            hour => 23, minute => 58, second => 20,
                            time_zone => 'UTC',
                          );
     my $t1 = $t->clone;
 
-    # 1971-12-31T23:59:20 UTC
+    # 1972-06-30T23:59:20 UTC
     $t->add( seconds => 60 );
-    is( $t->year, 1971, "year is 1971" );
+    is( $t->year, 1972, "year is 1972" );
     is( $t->minute, 59, "minute is 59" );
     is( $t->second, 20, "second is 20" );
 
-    # 1972-01-01T00:00:19 UTC
+    # 1972-07-01T00:00:19 UTC
     $t->add( seconds => 60 );
     is( $t->year, 1972, "year is 1972" );
     is( $t->minute, 0, "minute is 0" );
     is( $t->second, 19, "second is 19" );
 
-    # 1971-12-31T23:59:60 UTC
+    # 1972-06-30T23:59:60 UTC
     $t->subtract( seconds => 20 );
-    is( $t->year, 1971, "year is 1971" );
+    is( $t->year, 1972, "year is 1972" );
     is( $t->minute, 59, "minute is 59" );
     is( $t->second, 60, "second is 60" );
     is( $t->{utc_rd_secs} , 86400, "utc_rd_secs is 86400" );
 
 
     # subtract_datetime
-    my $t2 = DateTime->new( year => 1972, month => 1, day => 1,
+    my $t2 = DateTime->new( year => 1972, month => 07, day => 1,
                             hour => 0, minute => 0, second => 20,
                             time_zone => 'UTC',
                           );
@@ -83,24 +83,24 @@
     # tests using time zones
     # leap seconds occur during _UTC_ midnight
 
-    # 1971-12-31 20:58:20 -03:00 = 1971-12-31 23:58:20 UTC
-    my $t = DateTime->new( year => 1971, month => 12, day => 31,
+    # 1972-06-30 20:58:20 -03:00 = 1972-06-30 23:58:20 UTC
+    my $t = DateTime->new( year => 1972, month => 6, day => 30,
                            hour => 20, minute => 58, second => 20,
                            time_zone => 'America/Sao_Paulo',
                          );
 
     $t->add( seconds => 60 );
-    is( $t->datetime, '1971-12-31T20:59:20', "normal add" );
+    is( $t->datetime, '1972-06-30T20:59:20', "normal add" );
     is( $t->minute, 59, "min" );
     is( $t->second, 20, "sec" );
 
     $t->add( seconds => 60 );
-    is( $t->datetime, '1971-12-31T21:00:19', "add over a leap second" );
+    is( $t->datetime, '1972-06-30T21:00:19', "add over a leap second" );
     is( $t->minute, 0, "min" );
     is( $t->second, 19, "sec" );
 
     $t->subtract( seconds => 20 );
-    is( $t->datetime, '1971-12-31T20:59:60', "subtract over a leap second" );
+    is( $t->datetime, '1972-06-30T20:59:60', "subtract over a leap second" );
     is( $t->minute, 59, "min" );
     is( $t->second, 60, "sec" );
     is( $t->{utc_rd_secs} , 86400, "rd_sec" );
@@ -108,7 +108,7 @@
 
 # test that we can set second to 60
 {
-    my $t = DateTime->new( year => 1971, month => 12, day => 31,
+    my $t = DateTime->new( year => 1972, month => 6, day => 30,
                            hour => 20, minute => 59, second => 60,
                            time_zone => 'America/Sao_Paulo',
                          );
@@ -117,7 +117,7 @@
 }
 
 {
-    my $t = DateTime->new( year => 1971, month => 12, day => 31,
+    my $t = DateTime->new( year => 1972, month => 6, day => 30,
                            hour => 20, minute => 59, second => 60,
                            time_zone => 'America/Sao_Paulo',
                          );
@@ -131,33 +131,33 @@
     $t->add( days => 1 );
     $t->subtract( days => 1 );
 
-    is( $t->datetime, '1972-01-01T00:00:00',
+    is( $t->datetime, '1972-07-01T00:00:00',
         'add and subtract 1 day starting on leap second' );
 
     is( $t->leap_seconds, 1, 'datetime has 1 leap second' );
 }
 
 {
-    my $t = DateTime->new( year => 1971, month => 12, day => 31,
+    my $t = DateTime->new( year => 1972, month => 6, day => 30,
                            hour => 23, minute => 59, second => 59,
                            time_zone => 'UTC',
                          );
 
-    is( $t->epoch, 63071999, 'epoch just before first leap second is 63071999' );
+    is( $t->epoch, 78796799, 'epoch just before first leap second is 78796799' );
 
     $t->add( seconds => 1 );
 
-    is( $t->epoch, 63072000, 'epoch of first leap second is 63072000' );
+    is( $t->epoch, 78796800, 'epoch of first leap second is 78796800' );
 
     $t->add( seconds => 1 );
 
-    is( $t->epoch, 63072000, 'epoch of first second after first leap second is 
63072000' );
+    is( $t->epoch, 78796800, 'epoch of first second after first leap second is 
78796700' );
 }
 
 {
     my $dt = DateTime->new( year => 2003, time_zone => 'UTC' );
 
-    is( $dt->leap_seconds, 23, 'datetime has 23 leap seconds' );
+    is( $dt->leap_seconds, 22, 'datetime has 22 leap seconds' );
 }
 
 {
@@ -168,13 +168,13 @@
 
 # date math across leap seconds distinguishes between minutes and second
 {
-    my $t = DateTime->new( year => 1971, month => 12, day => 31,
+    my $t = DateTime->new( year => 1972, month => 12, day => 31,
                            hour => 23, minute => 59, second => 30,
                            time_zone => 'UTC' );
 
     $t->add( minutes => 1 );
 
-    is( $t->year, 1972, '+1 minute, year == 1972' );
+    is( $t->year, 1973, '+1 minute, year == 1973' );
     is( $t->month, 1, '+1 minute, month == 1' );
     is( $t->day, 1, '+1 minute, day == 1' );
     is( $t->hour, 0, '+1 minute, hour == 0' );
@@ -183,13 +183,13 @@
 }
 
 {
-    my $t = DateTime->new( year => 1971, month => 12, day => 31,
+    my $t = DateTime->new( year => 1972, month => 12, day => 31,
                            hour => 23, minute => 59, second => 30,
                            time_zone => 'UTC' );
 
     $t->add( seconds => 60 );
 
-    is( $t->year, 1972, '+60 seconds, year == 1972' );
+    is( $t->year, 1973, '+60 seconds, year == 1973' );
     is( $t->month, 1, '+60 seconds, month == 1' );
     is( $t->day, 1, '+60 seconds, day == 1' );
     is( $t->hour, 0, '+60 seconds, hour == 0' );
@@ -198,13 +198,13 @@
 }
 
 {
-    my $t = DateTime->new( year => 1971, month => 12, day => 31,
+    my $t = DateTime->new( year => 1972, month => 12, day => 31,
                            hour => 23, minute => 59, second => 30,
                            time_zone => 'UTC' );
 
     $t->add( minutes => 1, seconds => 1 );
 
-    is( $t->year, 1972, '+1 minute & 1 second, year == 1972' );
+    is( $t->year, 1973, '+1 minute & 1 second, year == 1973' );
     is( $t->month, 1, '+1 minute & 1 second, month == 1' );
     is( $t->day, 1, '+1 minute & 1 second, day == 1' );
     is( $t->hour, 0, '+1 minute & 1 second, hour == 0' );
@@ -213,19 +213,19 @@
 }
 
 {
-    eval { DateTime->new( year => 1971, month => 12, day => 31,
+    eval { DateTime->new( year => 1972, month => 12, day => 31,
                           hour => 23, minute => 59, second => 61,
                           time_zone => 'UTC',
                         ) };
     ok( $@, "Cannot give second of 61 except when it matches a leap second" );
 
-    eval { DateTime->new( year => 1971, month => 12, day => 31,
+    eval { DateTime->new( year => 1972, month => 12, day => 31,
                           hour => 23, minute => 58, second => 60,
                           time_zone => 'UTC',
                         ) };
     ok( $@, "Cannot give second of 60 except when it matches a leap second" );
 
-    eval { DateTime->new( year => 1971, month => 12, day => 31,
+    eval { DateTime->new( year => 1972, month => 12, day => 31,
                           hour => 23, minute => 59, second => 60,
                           time_zone => 'floating',
                         ) };
Index: t/26dt_leapsecond_pm.t
===================================================================
RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/t/26dt_leapsecond_pm.t,v
retrieving revision 1.2
diff -u -r1.2 26dt_leapsecond_pm.t
--- t/26dt_leapsecond_pm.t      2 Dec 2003 05:10:51 -0000       1.2
+++ t/26dt_leapsecond_pm.t      19 Jul 2004 02:23:33 -0000
@@ -8,38 +8,37 @@
 
 # at the start of the table:
 
-# 1971-12-31
-my $day = 719892;
+# 1972-06-30
+my $day = 720074;
 is ( DateTime::LeapSecond::leap_seconds( $day ), 0, 'before leap-second transition'  
);
 
 is ( DateTime::LeapSecond::extra_seconds( $day ) + 0, 1, 'leap day'  );
 
-# 1972-01-01
-$day = 719893;
+# 1972-07-01
+$day = 720075;
 is ( DateTime::LeapSecond::leap_seconds( $day ), 1, 'day after leap-second day'  );
 
 is ( DateTime::LeapSecond::extra_seconds( $day ), 0, 'not a leap day'  );
 
-# 1972-01-02
-$day = 719894;
+# 1972-07-02
+$day = 720076;
 is ( DateTime::LeapSecond::leap_seconds( $day ), 1, 'after leap-second day'  );
 
 # at the end of the table:
 # 1998-12-31
 $day = 729754;
-is ( DateTime::LeapSecond::leap_seconds( $day ), 22, 'before leap-second day'  );
+is ( DateTime::LeapSecond::leap_seconds( $day ), 21, 'before leap-second day'  );
 
 # 1999-01-01
 $day = 729755;
-is ( DateTime::LeapSecond::leap_seconds( $day ), 23, 'leap-second day'  );
+is ( DateTime::LeapSecond::leap_seconds( $day ), 22, 'leap-second day'  );
 
 # 1999-01-02
 $day = 729756;
-is ( DateTime::LeapSecond::leap_seconds( $day ), 23, 'after leap-second day'  );
+is ( DateTime::LeapSecond::leap_seconds( $day ), 22, 'after leap-second day'  );
 
 
 # some leap second dates:
-# 1972  Jan. 1
 # 1972  Jul. 1
 # 1973  Jan. 1
 # ...

Reply via email to