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