Fix previous conflict.
[bpt/emacs.git] / src / mktime.c
CommitLineData
68c45bf0 1/* Convert a `struct tm' to a time_t value.
429ab54e
GM
2 Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
98f1928d
PE
4 Contributed by Paul Eggert (eggert@twinsun.com).
5
89752145 6 NOTE: The canonical source of this file is maintained with the GNU C Library.
06bd27fd 7 Bugs can be reported to bug-glibc@gnu.org.
98f1928d 8
89752145
PE
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
98f1928d 13
89752145
PE
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
98f1928d 18
89752145
PE
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
4fc5845f 21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
89752145 22 USA. */
98f1928d
PE
23
24/* Define this to have a standalone program to test this implementation of
25 mktime. */
26/* #define DEBUG 1 */
27
28#ifdef HAVE_CONFIG_H
6385ec2b 29# include <config.h>
98f1928d
PE
30#endif
31
32#ifdef _LIBC
33# define HAVE_LIMITS_H 1
98f1928d
PE
34# define STDC_HEADERS 1
35#endif
36
37/* Assume that leap seconds are possible, unless told otherwise.
38 If the host has a `zic' command with a `-L leapsecondfilename' option,
39 then it supports leap seconds; otherwise it probably doesn't. */
40#ifndef LEAP_SECONDS_POSSIBLE
6385ec2b 41# define LEAP_SECONDS_POSSIBLE 1
98f1928d
PE
42#endif
43
44#include <sys/types.h> /* Some systems define `time_t' here. */
45#include <time.h>
46
47#if HAVE_LIMITS_H
6385ec2b 48# include <limits.h>
98f1928d
PE
49#endif
50
51#if DEBUG
6385ec2b
PE
52# include <stdio.h>
53# if STDC_HEADERS
54# include <stdlib.h>
55# endif
98f1928d 56/* Make it work even if the system's libc has its own mktime routine. */
6385ec2b 57# define mktime my_mktime
98f1928d
PE
58#endif /* DEBUG */
59
98f1928d 60#ifndef CHAR_BIT
6385ec2b 61# define CHAR_BIT 8
98f1928d
PE
62#endif
63
067cc4dc
UD
64/* The extra casts work around common compiler bugs. */
65#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
66/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
67 It is necessary at least when t == time_t. */
68#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
69 ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
06bd27fd 70#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
067cc4dc 71
98f1928d 72#ifndef INT_MIN
067cc4dc 73# define INT_MIN TYPE_MINIMUM (int)
98f1928d
PE
74#endif
75#ifndef INT_MAX
067cc4dc 76# define INT_MAX TYPE_MAXIMUM (int)
98f1928d
PE
77#endif
78
79#ifndef TIME_T_MIN
067cc4dc 80# define TIME_T_MIN TYPE_MINIMUM (time_t)
98f1928d
PE
81#endif
82#ifndef TIME_T_MAX
067cc4dc 83# define TIME_T_MAX TYPE_MAXIMUM (time_t)
98f1928d
PE
84#endif
85
86#define TM_YEAR_BASE 1900
87#define EPOCH_YEAR 1970
88
89#ifndef __isleap
90/* Nonzero if YEAR is a leap year (every 4 years,
91 except every 100th isn't, and every 400th is). */
6385ec2b 92# define __isleap(year) \
98f1928d
PE
93 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
94#endif
95
96/* How many days come before each month (0-12). */
97const unsigned short int __mon_yday[2][13] =
98 {
99 /* Normal years. */
100 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
101 /* Leap years. */
102 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
103 };
104
98f1928d
PE
105
106#ifdef _LIBC
68c45bf0 107# define my_mktime_localtime_r __localtime_r
98f1928d 108#else
68c45bf0
PE
109/* If we're a mktime substitute in a GNU program, then prefer
110 localtime to localtime_r, since many localtime_r implementations
111 are buggy. */
98f1928d 112static struct tm *
998e9f8c
DL
113my_mktime_localtime_r (t, tp)
114 const time_t *t;
115 struct tm *tp;
98f1928d
PE
116{
117 struct tm *l = localtime (t);
118 if (! l)
119 return 0;
120 *tp = *l;
121 return tp;
122}
98f1928d
PE
123#endif /* ! _LIBC */
124
125
126/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
127 measured in seconds, ignoring leap seconds.
128 YEAR uses the same numbering as TM->tm_year.
129 All values are in range, except possibly YEAR.
649e97a3 130 If TP is null, return a nonzero value.
98f1928d
PE
131 If overflow occurs, yield the low order bits of the correct answer. */
132static time_t
998e9f8c
DL
133ydhms_tm_diff (year, yday, hour, min, sec, tp)
134 int year, yday, hour, min, sec;
135 const struct tm *tp;
98f1928d 136{
649e97a3
UD
137 if (!tp)
138 return 1;
139 else
140 {
141 /* Compute intervening leap days correctly even if year is negative.
142 Take care to avoid int overflow. time_t overflow is OK, since
143 only the low order bits of the correct time_t answer are needed.
144 Don't convert to time_t until after all divisions are done, since
145 time_t might be unsigned. */
146 int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
147 int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
148 int a100 = a4 / 25 - (a4 % 25 < 0);
149 int b100 = b4 / 25 - (b4 % 25 < 0);
150 int a400 = a100 >> 2;
151 int b400 = b100 >> 2;
152 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
153 time_t years = year - (time_t) tp->tm_year;
154 time_t days = (365 * years + intervening_leap_days
155 + (yday - tp->tm_yday));
156 return (60 * (60 * (24 * days + (hour - tp->tm_hour))
157 + (min - tp->tm_min))
158 + (sec - tp->tm_sec));
159 }
98f1928d
PE
160}
161
649e97a3
UD
162/* Use CONVERT to convert *T to a broken down time in *TP.
163 If *T is out of range for conversion, adjust it so that
164 it is the nearest in-range value and then convert that. */
165static struct tm *
998e9f8c
DL
166ranged_convert (convert, t, tp)
167#ifdef PROTOTYPES
168 struct tm *(*convert) (const time_t *, struct tm *);
169#else
170 struct tm *(*convert)();
171#endif
172 time_t *t;
173 struct tm *tp;
649e97a3
UD
174{
175 struct tm *r;
176
177 if (! (r = (*convert) (t, tp)) && *t)
178 {
179 time_t bad = *t;
180 time_t ok = 0;
181 struct tm tm;
182
183 /* BAD is a known unconvertible time_t, and OK is a known good one.
184 Use binary search to narrow the range between BAD and OK until
185 they differ by 1. */
186 while (bad != ok + (bad < 0 ? -1 : 1))
187 {
188 time_t mid = *t = (bad < 0
189 ? bad + ((ok - bad) >> 1)
190 : ok + ((bad - ok) >> 1));
191 if ((r = (*convert) (t, tp)))
192 {
193 tm = *r;
194 ok = mid;
195 }
196 else
197 bad = mid;
198 }
199
200 if (!r && ok)
201 {
202 /* The last conversion attempt failed;
203 revert to the most recent successful attempt. */
204 *t = ok;
205 *tp = tm;
206 r = tp;
207 }
208 }
209
210 return r;
211}
212
213
98f1928d
PE
214/* Convert *TP to a time_t value, inverting
215 the monotonic and mostly-unit-linear conversion function CONVERT.
216 Use *OFFSET to keep track of a guess at the offset of the result,
217 compared to what the result would be for UTC without leap seconds.
218 If *OFFSET's guess is correct, only one CONVERT call is needed. */
219time_t
998e9f8c
DL
220__mktime_internal (tp, convert, offset)
221 struct tm *tp;
222#ifdef PROTOTYPES
223 struct tm *(*convert) (const time_t *, struct tm *);
224#else
225 struct tm *(*convert)();
226#endif
227 time_t *offset;
98f1928d 228{
68c45bf0 229 time_t t, dt, t0, t1, t2;
98f1928d
PE
230 struct tm tm;
231
232 /* The maximum number of probes (calls to CONVERT) should be enough
233 to handle any combinations of time zone rule changes, solar time,
68c45bf0
PE
234 leap seconds, and oscillations around a spring-forward gap.
235 POSIX.1 prohibits leap seconds, but some hosts have them anyway. */
236 int remaining_probes = 6;
98f1928d
PE
237
238 /* Time requested. Copy it in case CONVERT modifies *TP; this can
239 occur if TP is localtime's returned value and CONVERT is localtime. */
240 int sec = tp->tm_sec;
241 int min = tp->tm_min;
242 int hour = tp->tm_hour;
243 int mday = tp->tm_mday;
244 int mon = tp->tm_mon;
245 int year_requested = tp->tm_year;
246 int isdst = tp->tm_isdst;
247
984257db
DL
248 /* 1 if the previous probe was DST. */
249 int dst2;
250
98f1928d
PE
251 /* Ensure that mon is in range, and set year accordingly. */
252 int mon_remainder = mon % 12;
253 int negative_mon_remainder = mon_remainder < 0;
254 int mon_years = mon / 12 - negative_mon_remainder;
255 int year = year_requested + mon_years;
256
257 /* The other values need not be in range:
258 the remaining code handles minor overflows correctly,
259 assuming int and time_t arithmetic wraps around.
260 Major overflows are caught at the end. */
261
262 /* Calculate day of year from year, month, and day of month.
263 The result need not be in range. */
264 int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
265 [mon_remainder + 12 * negative_mon_remainder])
266 + mday - 1);
267
89752145 268 int sec_requested = sec;
984257db
DL
269
270 /* Only years after 1970 are defined.
271 If year is 69, it might still be representable due to
272 timezone differences. */
273 if (year < 69)
274 return -1;
275
98f1928d
PE
276#if LEAP_SECONDS_POSSIBLE
277 /* Handle out-of-range seconds specially,
278 since ydhms_tm_diff assumes every minute has 60 seconds. */
98f1928d
PE
279 if (sec < 0)
280 sec = 0;
281 if (59 < sec)
282 sec = 59;
283#endif
284
285 /* Invert CONVERT by probing. First assume the same offset as last time.
286 Then repeatedly use the error to improve the guess. */
287
288 tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
289 tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
290 t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
291
984257db 292 for (t = t1 = t2 = t0 + *offset, dst2 = 0;
649e97a3
UD
293 (dt = ydhms_tm_diff (year, yday, hour, min, sec,
294 ranged_convert (convert, &t, &tm)));
984257db 295 t1 = t2, t2 = t, t += dt, dst2 = tm.tm_isdst != 0)
68c45bf0 296 if (t == t1 && t != t2
984257db
DL
297 && (tm.tm_isdst < 0
298 || (isdst < 0
299 ? dst2 <= (tm.tm_isdst != 0)
300 : (isdst != 0) != (tm.tm_isdst != 0))))
68c45bf0
PE
301 /* We can't possibly find a match, as we are oscillating
302 between two values. The requested time probably falls
303 within a spring-forward gap of size DT. Follow the common
304 practice in this case, which is to return a time that is DT
305 away from the requested time, preferring a time whose
984257db
DL
306 tm_isdst differs from the requested value. (If no tm_isdst
307 was requested and only one of the two values has a nonzero
308 tm_isdst, prefer that value.) In practice, this is more
309 useful than returning -1. */
68c45bf0
PE
310 break;
311 else if (--remaining_probes == 0)
98f1928d
PE
312 return -1;
313
68c45bf0
PE
314 /* If we have a match, check whether tm.tm_isdst has the requested
315 value, if any. */
316 if (dt == 0 && isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst)
98f1928d 317 {
68c45bf0
PE
318 /* tm.tm_isdst has the wrong value. Look for a neighboring
319 time with the right value, and use its UTC offset.
320 Heuristic: probe the previous three calendar quarters (approximately),
321 looking for the desired isdst. This isn't perfect,
322 but it's good enough in practice. */
323 int quarter = 7889238; /* seconds per average 1/4 Gregorian year */
324 int i;
325
326 /* If we're too close to the time_t limit, look in future quarters. */
327 if (t < TIME_T_MIN + 3 * quarter)
328 quarter = -quarter;
329
330 for (i = 1; i <= 3; i++)
98f1928d 331 {
68c45bf0
PE
332 time_t ot = t - i * quarter;
333 struct tm otm;
334 ranged_convert (convert, &ot, &otm);
335 if (otm.tm_isdst == isdst)
98f1928d 336 {
68c45bf0
PE
337 /* We found the desired tm_isdst.
338 Extrapolate back to the desired time. */
339 t = ot + ydhms_tm_diff (year, yday, hour, min, sec, &otm);
340 ranged_convert (convert, &t, &tm);
341 break;
98f1928d
PE
342 }
343 }
344 }
345
346 *offset = t - t0;
347
348#if LEAP_SECONDS_POSSIBLE
349 if (sec_requested != tm.tm_sec)
350 {
351 /* Adjust time to reflect the tm_sec requested, not the normalized value.
352 Also, repair any damage from a false match due to a leap second. */
353 t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
649e97a3
UD
354 if (! (*convert) (&t, &tm))
355 return -1;
98f1928d
PE
356 }
357#endif
358
359 if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
360 {
361 /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
362 so check for major overflows. A gross check suffices,
363 since if t has overflowed, it is off by a multiple of
364 TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
365 the difference that is bounded by a small value. */
366
367 double dyear = (double) year_requested + mon_years - tm.tm_year;
368 double dday = 366 * dyear + mday;
369 double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
370
067cc4dc
UD
371 /* On Irix4.0.5 cc, dividing TIME_T_MIN by 3 does not produce
372 correct results, ie., it erroneously gives a positive value
373 of 715827882. Setting a variable first then doing math on it
374 seems to work. (ghazi@caip.rutgers.edu) */
375
376 const time_t time_t_max = TIME_T_MAX;
377 const time_t time_t_min = TIME_T_MIN;
378
379 if (time_t_max / 3 - time_t_min / 3 < (dsec < 0 ? - dsec : dsec))
98f1928d
PE
380 return -1;
381 }
382
984257db
DL
383 if (year == 69)
384 {
385 /* If year was 69, need to check whether the time was representable
386 or not. */
387 if (t < 0 || t > 2 * 24 * 60 * 60)
388 return -1;
389 }
390
98f1928d
PE
391 *tp = tm;
392 return t;
393}
394
68c45bf0
PE
395
396static time_t localtime_offset;
397
398/* Convert *TP to a time_t value. */
399time_t
400mktime (tp)
401 struct tm *tp;
402{
403#ifdef _LIBC
404 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
405 time zone names contained in the external variable `tzname' shall
406 be set as if the tzset() function had been called. */
407 __tzset ();
408#endif
409
410 return __mktime_internal (tp, my_mktime_localtime_r, &localtime_offset);
411}
412
98f1928d
PE
413#ifdef weak_alias
414weak_alias (mktime, timelocal)
415#endif
416\f
417#if DEBUG
418
419static int
420not_equal_tm (a, b)
421 struct tm *a;
422 struct tm *b;
423{
424 return ((a->tm_sec ^ b->tm_sec)
425 | (a->tm_min ^ b->tm_min)
426 | (a->tm_hour ^ b->tm_hour)
427 | (a->tm_mday ^ b->tm_mday)
428 | (a->tm_mon ^ b->tm_mon)
429 | (a->tm_year ^ b->tm_year)
430 | (a->tm_mday ^ b->tm_mday)
431 | (a->tm_yday ^ b->tm_yday)
432 | (a->tm_isdst ^ b->tm_isdst));
433}
434
435static void
436print_tm (tp)
437 struct tm *tp;
438{
649e97a3
UD
439 if (tp)
440 printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
441 tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
442 tp->tm_hour, tp->tm_min, tp->tm_sec,
443 tp->tm_yday, tp->tm_wday, tp->tm_isdst);
444 else
445 printf ("0");
98f1928d
PE
446}
447
448static int
649e97a3 449check_result (tk, tmk, tl, lt)
98f1928d
PE
450 time_t tk;
451 struct tm tmk;
452 time_t tl;
649e97a3 453 struct tm *lt;
98f1928d 454{
649e97a3 455 if (tk != tl || !lt || not_equal_tm (&tmk, lt))
98f1928d
PE
456 {
457 printf ("mktime (");
458 print_tm (&tmk);
459 printf (")\nyields (");
649e97a3 460 print_tm (lt);
98f1928d
PE
461 printf (") == %ld, should be %ld\n", (long) tl, (long) tk);
462 return 1;
463 }
464
465 return 0;
466}
467
468int
469main (argc, argv)
470 int argc;
471 char **argv;
472{
473 int status = 0;
474 struct tm tm, tmk, tml;
649e97a3 475 struct tm *lt;
98f1928d
PE
476 time_t tk, tl;
477 char trailer;
478
479 if ((argc == 3 || argc == 4)
480 && (sscanf (argv[1], "%d-%d-%d%c",
481 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
482 == 3)
483 && (sscanf (argv[2], "%d:%d:%d%c",
484 &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
485 == 3))
486 {
487 tm.tm_year -= TM_YEAR_BASE;
488 tm.tm_mon--;
489 tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
490 tmk = tm;
491 tl = mktime (&tmk);
649e97a3
UD
492 lt = localtime (&tl);
493 if (lt)
494 {
495 tml = *lt;
496 lt = &tml;
497 }
98f1928d
PE
498 printf ("mktime returns %ld == ", (long) tl);
499 print_tm (&tmk);
500 printf ("\n");
649e97a3 501 status = check_result (tl, tmk, tl, lt);
98f1928d
PE
502 }
503 else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
504 {
505 time_t from = atol (argv[1]);
506 time_t by = atol (argv[2]);
507 time_t to = atol (argv[3]);
508
509 if (argc == 4)
510 for (tl = from; tl <= to; tl += by)
511 {
649e97a3
UD
512 lt = localtime (&tl);
513 if (lt)
514 {
515 tmk = tml = *lt;
516 tk = mktime (&tmk);
517 status |= check_result (tk, tmk, tl, tml);
518 }
519 else
520 {
521 printf ("localtime (%ld) yields 0\n", (long) tl);
522 status = 1;
523 }
98f1928d
PE
524 }
525 else
526 for (tl = from; tl <= to; tl += by)
527 {
528 /* Null benchmark. */
649e97a3
UD
529 lt = localtime (&tl);
530 if (lt)
531 {
532 tmk = tml = *lt;
533 tk = tl;
534 status |= check_result (tk, tmk, tl, tml);
535 }
536 else
537 {
538 printf ("localtime (%ld) yields 0\n", (long) tl);
539 status = 1;
540 }
98f1928d
PE
541 }
542 }
543 else
544 printf ("Usage:\
545\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
546\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
547\t%s FROM BY TO - # Do not test those values (for benchmark).\n",
548 argv[0], argv[0], argv[0]);
549
550 return status;
551}
552
553#endif /* DEBUG */
554\f
555/*
556Local Variables:
68c45bf0 557compile-command: "gcc -DDEBUG -DHAVE_LIMITS_H -DSTDC_HEADERS -Wall -W -O -g mktime.c -o mktime"
98f1928d
PE
558End:
559*/
ab5796a9
MB
560
561/* arch-tag: 9456752f-7ddd-47cb-8286-fa807b1355ae
562 (do not change this comment) */