timezone stuff on 64 bit machines
Arthur David Olson
ado
Mon Oct 23 14:56:45 UTC 1995
>> The fix is to use the fact that--at least for now--the calendar operates on
>> a grand 2800-year cycle: any set of 2800 consecutive years contains exactly
>> 1,022,679 days. A bit of modular arithmetic will get us where we want to be.
>
> To me this calls attention to a fundamental design flaw: any
> computation of daylight savings time that involves looping a
> billion times, or even a thousand, cannot be right. Under what
> circumstances does this happen?
The attached might be used to avoid thousands of loops.
--ado
SCCS/s.localtime.c: 7.45 vs. 7.48
*** 7.45/localtime.c Mon Oct 23 10:48:43 1995
--- 7.48/localtime.c Mon Oct 23 10:48:45 1995
***************
*** 1,6 ****
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)localtime.c 7.45";
#endif /* !defined NOID */
#endif /* !defined lint */
--- 1,6 ----
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)localtime.c 7.48";
#endif /* !defined NOID */
#endif /* !defined lint */
***************
*** 1173,1191 ****
if (tmp->tm_wday < 0)
tmp->tm_wday += DAYSPERWEEK;
y = EPOCH_YEAR;
! if (days >= 0)
! for ( ; ; ) {
! yleap = isleap(y);
! if (days < (long) year_lengths[yleap])
! break;
! ++y;
! days = days - (long) year_lengths[yleap];
! }
! else do {
! --y;
! yleap = isleap(y);
! days = days + (long) year_lengths[yleap];
! } while (days < 0);
tmp->tm_year = y - TM_YEAR_BASE;
tmp->tm_yday = (int) days;
ip = mon_lengths[yleap];
--- 1173,1190 ----
if (tmp->tm_wday < 0)
tmp->tm_wday += DAYSPERWEEK;
y = EPOCH_YEAR;
! #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
! while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
! register int newy;
!
! newy = y + days / DAYSPERNYEAR;
! if (days < 0)
! --newy;
! days -= (newy - y) * DAYSPERNYEAR +
! LEAPS_THRU_END_OF(newy - 1) -
! LEAPS_THRU_END_OF(y - 1);
! y = newy;
! }
tmp->tm_year = y - TM_YEAR_BASE;
tmp->tm_yday = (int) days;
ip = mon_lengths[yleap];
More information about the tz
mailing list