bug in mktime() normalization?
Olson, Arthur David
OLSONA at dc37a.nci.nih.gov
Mon Aug 25 17:24:49 UTC 1997
Below find changes to localtime.c designed to deal with the situation
described by Tom Peterson.
The challenge we're faced with is that we don't want to prematurely
normalize the tm_sec field
in a structure passed to "mktime"--the field might contain a value
associated with a leap second.
The approach taken below is to first do things without normalizing but,
if that fails, to do things using normalization.
My check indicates that this approach gives the desired behavior in the
example program provided by Tom.
--ado
*** 7.61/localtime.c Mon Aug 25 13:23:24 1997
--- 7.62/localtime.c Mon Aug 25 13:23:25 1997
***************
*** 5,11 ****
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)localtime.c 7.61";
#endif /* !defined NOID */
#endif /* !defined lint */
--- 5,11 ----
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)localtime.c 7.62";
#endif /* !defined NOID */
#endif /* !defined lint */
***************
*** 134,139 ****
--- 134,143 ----
void(*funcp) P((const time_t *,
long, struct tm*)),
long offset, int * okayp));
+ static time_t time2sub P((struct tm *tmp,
+ void(*funcp) P((const time_t *,
+ long, struct tm*)),
+ long offset, int * okayp, int
do_norm_secs));
static void timesub P((const time_t * timep, long offset,
const struct state * sp, struct tm *
tmp));
static int tmcomp P((const struct tm * atmp,
***************
*** 1276,1286 ****
}
static time_t
! time2(tmp, funcp, offset, okayp)
struct tm * const tmp;
void (* const funcp) P((const time_t*, long, struct tm*));
const long offset;
int * const okayp;
{
register const struct state * sp;
register int dir;
--- 1280,1291 ----
}
static time_t
! time2sub(tmp, funcp, offset, okayp, do_norm_secs)
struct tm * const tmp;
void (* const funcp) P((const time_t*, long, struct tm*));
const long offset;
int * const okayp;
+ const int do_norm_secs;
{
register const struct state * sp;
register int dir;
***************
*** 1293,1298 ****
--- 1298,1308 ----
*okayp = FALSE;
yourtm = *tmp;
+ if (do_norm_secs) {
+ if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
+ SECSPERMIN))
+ return WRONG;
+ }
if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min,
MINSPERHOUR))
return WRONG;
if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour,
HOURSPERDAY))
***************
*** 1421,1426 ****
--- 1431,1454 ----
return t;
}
+ static time_t
+ time2(tmp, funcp, offset, okayp)
+ struct tm * const tmp;
+ void (* const funcp) P((const time_t*, long, struct tm*));
+ const long offset;
+ int * const okayp;
+ {
+ time_t t;
+
+ /*
+ ** First try without normalization of seconds
+ ** (in case tm_sec contains a value associated with a leap
second).
+ ** If that fails, try with normalization of seconds.
+ */
+ t = time2sub(tmp, funcp, offset, okayp, FALSE);
+ return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
+ }
+
static time_t
time1(tmp, funcp, offset)
struct tm * const tmp;
More information about the tz
mailing list