This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
A revised time patch
- To: libc-hacker@cygnus.com (GNU C Library)
- Subject: A revised time patch
- From: hjl@lucon.org (H.J. Lu)
- Date: Fri, 30 Oct 1998 17:54:14 -0800 (PST)
Hi,
Here is a revised time patch. Now it passes all mktime
tests in VSX-PCT. The testcase is in my previous email.
BTW, you also need my timezone patch.
Thanks.
--
H.J. Lu (hjl@gnu.org)
---
Fri Oct 30 17:48:48 1998 H.J. Lu <hjl@gnu.org>
* time/mktime.c (__mktime_internal): Handle the case where
tm_isdst is different from __daylight != 0 correctly.
* time/tzfile (__tzfile_read): Set __daylight to the difference
between DST and STD.
(__tzfile_compute): Likewise.
* time/tzset.c (tz_compute): Likewise.
Index: time/mktime.c
===================================================================
RCS file: /home/work/cvs/gnu/glibc/time/mktime.c,v
retrieving revision 1.1.1.13
diff -u -p -r1.1.1.13 mktime.c
--- time/mktime.c 1998/10/17 02:11:00 1.1.1.13
+++ time/mktime.c 1998/10/31 01:45:11
@@ -334,10 +334,13 @@ __mktime_internal (tp, convert, offset)
(dt = ydhms_tm_diff (year, yday, hour, min, sec,
ranged_convert (convert, &t, &tm)));
t1 = t2, t2 = t, t += dt)
- if (t == t1 && t != t2
- && (isdst < 0 || tm.tm_isdst < 0
- || (isdst != 0) != (tm.tm_isdst != 0)))
- /* We can't possibly find a match, as we are oscillating
+ if ((0 <= isdst && 0 <= tm.tm_isdst
+ && dt == __daylight * ((isdst != 0) - (tm.tm_isdst != 0)))
+ || (t == t1 && t != t2
+ && (isdst < 0 || tm.tm_isdst < 0
+ || (isdst != 0) != (tm.tm_isdst != 0))))
+ /* We find a match due to difference between STD and DST. Or
+ we can't possibly find a match, as we are oscillating
between two values. The requested time probably falls
within a spring-forward gap of size DT. Follow the common
practice in this case, which is to return a time that is DT
@@ -355,11 +358,11 @@ __mktime_internal (tp, convert, offset)
int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
if (dst_diff)
{
- /* Move two hours in the direction indicated by the disagreement,
- probe some more, and switch to a new time if found.
- The largest known fallback due to daylight savings is two hours:
- once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
- time_t ot = t - 2 * 60 * 60 * dst_diff;
+ /* Move __daylight seconds in the direction indicated by the
+ disagreement, probe some more, and switch to a new time
+ if found. The fallback due to daylight savings is stored
+ in __daylight. */
+ time_t ot = t - __daylight * dst_diff;
while (--remaining_probes != 0)
{
struct tm otm;
Index: time/tzfile.c
===================================================================
RCS file: /home/work/cvs/gnu/glibc/time/tzfile.c,v
retrieving revision 1.1.1.13
diff -u -p -r1.1.1.13 tzfile.c
--- time/tzfile.c 1998/10/26 15:33:26 1.1.1.13
+++ time/tzfile.c 1998/10/28 17:32:31
@@ -298,7 +298,7 @@ __tzfile_read (const char *file)
}
}
- __daylight = rule_stdoff != rule_dstoff;
+ __daylight = rule_dstoff - rule_stdoff;
__timezone = -rule_stdoff;
__use_tzfile = 1;
@@ -436,7 +436,7 @@ __tzfile_compute (time_t timer, int use_
if (use_localtime)
{
struct ttinfo *info = find_transition (timer);
- __daylight = rule_stdoff != rule_dstoff;
+ __daylight = rule_dstoff - rule_stdoff;
__timezone = -rule_stdoff;
__tzname[1] = NULL;
for (i = 0; i < num_types; ++i)
Index: time/tzset.c
===================================================================
RCS file: /home/work/cvs/gnu/glibc/time/tzset.c,v
retrieving revision 1.1.1.16
diff -u -p -r1.1.1.16 tzset.c
--- time/tzset.c 1998/10/26 23:24:25 1.1.1.16
+++ time/tzset.c 1998/10/28 17:34:50
@@ -528,7 +528,7 @@ tz_compute (timer, tm)
&& ! compute_change (&tz_rules[1], 1900 + tm->tm_year + 1))
return 0;
- __daylight = tz_rules[0].offset != tz_rules[1].offset;
+ __daylight = tz_rules[1].offset - tz_rules[0].offset;
__timezone = -tz_rules[0].offset;
__tzname[0] = (char *) tz_rules[0].name;
__tzname[1] = (char *) tz_rules[1].name;