zic leapseconds bug

David Robinson drtr at apache.org
Tue Jun 13 15:07:15 UTC 2006

There appears to be a bug in zic when leapseconds are provided, for any 
time zone transition near a leapsecond.

The bug is that after reading in the Leaps as Posix seconds in the trans[] 
array, adjleap() is called. This converts these to genuine UTC seconds.
However, this array is then used to fixup transition times which are in 
posix seconds, by
 	for (i = 0; i < timecnt; ++i) {
 		j = leapcnt;
 		while (--j >= 0)
 			if (ats[i] >= trans[j]) {
 				ats[i] = tadd(ats[i], corr[j]);

ats[] is stored in posix seconds, but trans[] is in leap seconds.

The effect is that for Europe/London, the transition on 1996-01-01 
00:00:00 is actually set to be at 1995-12-31 23:59:60, i.e. on the leap 
second (820454419). Any transition in the range 1996-01-01 00:00:00 to 
00:00:18 is similarly off by one second.

The fix is obvious in principle (have a copy of trans[] that isn't 
leap-second adjusted, and use that in the code above), but not all the 
uses of trans[] in the code are obvious to me (what are Rolling 

I'd also suggest that zic reject any transition in its input with a 
second=60. It's usually run without a leap file so there's no point in 
implementing the correct behaviour for that case.

Many thanks,

  David Robinson

More information about the tz mailing list