diff options
author | Eric Andersen <andersen@codepoet.org> | 2006-11-02 21:46:07 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2006-11-02 21:46:07 +0000 |
commit | 52c61a7571ab46e6e485861841d160ac26400181 (patch) | |
tree | 632bbdddb6b1641a859d805b00928001ef4e4918 | |
parent | b8f5be70c4ccaded6b37096f56f1a6e86c96572c (diff) |
In bug 622, JohnAta writes:
In 2005, Congress passed a law so that in 2007, the second week of March starts
DST. Previously, it was the first week of April. The uclibc time library
routines apparently have not been updated to reflect this new processing. Using
the current version of uclibc, on March 11, 2007 the reported time will be
incorrect.
-rw-r--r-- | libc/misc/time/time.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c index 93afa9b68..37e1700cd 100644 --- a/libc/misc/time/time.c +++ b/libc/misc/time/time.c @@ -195,6 +195,21 @@ libc_hidden_proto(__ctype_b) #define TZNAME_MAX _POSIX_TZNAME_MAX #endif +#if defined (L_tzset) || defined (L_localtime_r) || defined(L_strftime) || \ + defined(L__time_mktime) || defined(L__time_mktime_tzi) + +void _time_tzset(int use_old_rules); +libc_hidden_proto(_time_tzset) + +#ifndef L__time_mktime + + /* Jan 1, 2007 Z - tm = 0,0,0,1,0,107,1,0,0 */ + +const static time_t new_rule_starts = 1167609600; + +#endif +#endif + /**********************************************************************/ /* The era code is currently unfinished. */ /* #define ENABLE_ERA_CODE */ @@ -590,7 +605,7 @@ struct tm *localtime_r(register const time_t *__restrict timer, { TZLOCK; - tzset(); + _time_tzset(*timer < new_rule_starts); __time_localtime_tzi(timer, result, _time_tzinfo); @@ -1028,7 +1043,8 @@ size_t __XL_NPP(strftime)(char *__restrict s, size_t maxsize, unsigned char mod; unsigned char code; - tzset(); /* We'll, let's get this out of the way. */ + /* We'll, let's get this out of the way. */ + _time_tzset(_time_mktime((struct tm *) timeptr, 0) < new_rule_starts); lvl = 0; p = format; @@ -1717,7 +1733,9 @@ static const char vals[] = { 6, 0, 0, /* Note: overloaded for non-M non-J case... */ 0, 1, 0, /* J */ ',', 'M', '4', '.', '1', '.', '0', - ',', 'M', '1', '0', '.', '5', '.', '0', 0 + ',', 'M', '1', '0', '.', '5', '.', '0', 0, + ',', 'M', '3', '.', '2', '.', '0', + ',', 'M', '1', '1', '.', '1', '.', '0', 0 }; #define TZ vals @@ -1725,6 +1743,7 @@ static const char vals[] = { #define RANGE (vals + 7) #define RULE (vals + 11 - 1) #define DEFAULT_RULES (vals + 22) +#define DEFAULT_2007_RULES (vals + 38) /* Initialize to UTC. */ int daylight = 0; @@ -1853,6 +1872,11 @@ libc_hidden_proto(isascii) void tzset(void) { + _time_tzset((time(NULL)) < new_rule_starts); +} + +void _time_tzset(int use_old_rules) +{ register const char *e; register char *s; long off; @@ -1975,7 +1999,15 @@ void tzset(void) } else { /* OK, we have dst, so get some rules. */ count = 0; if (!*e) { /* No rules so default to US rules. */ - e = DEFAULT_RULES; + e = use_old_rules ? DEFAULT_RULES : DEFAULT_2007_RULES; +#ifdef DEBUG_TZSET + if (e == DEFAULT_RULES) + printf("tzset: Using old rules.\n"); + else if (e == DEFAULT_2007_RULES) + printf("tzset: Using new rules\n"); + else + printf("tzset: Using undefined rules\n"); +#endif /* DEBUG_TZSET */ } do { @@ -2314,6 +2346,8 @@ time_t attribute_hidden _time_mktime_tzi(struct tm *timeptr, int store_on_succes --d; } + _time_tzset (x.tm_year < 2007); /* tm_year was expanded above */ + #ifdef __BCC__ d = p[5] - 1; days = -719163L + ((long)d)*365 + ((d/4) - (d/100) + (d/400) + p[3] + p[7]); |