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