summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2006-11-02 21:46:07 +0000
committerEric Andersen <andersen@codepoet.org>2006-11-02 21:46:07 +0000
commit52c61a7571ab46e6e485861841d160ac26400181 (patch)
tree632bbdddb6b1641a859d805b00928001ef4e4918 /libc
parentb8f5be70c4ccaded6b37096f56f1a6e86c96572c (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.
Diffstat (limited to 'libc')
-rw-r--r--libc/misc/time/time.c42
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]);