6eb9bfc72ddd64d4e04ca459785de4edaada43a9
[gnulib.git] / lib / mktime.c
1 /* Convert a `struct tm' to a time_t value.
2    Copyright (C) 1993-1999, 2002-2007, 2009-2011 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Paul Eggert <eggert@twinsun.com>.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License along
17    with this program; if not, write to the Free Software Foundation,
18    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19
20 /* Define this to have a standalone program to test this implementation of
21    mktime.  */
22 /* #define DEBUG 1 */
23
24 #ifndef _LIBC
25 # include <config.h>
26 #endif
27
28 /* Some of the code in this file assumes that signed integer overflow
29    silently wraps around.  This assumption can't easily be programmed
30    around, nor can it be checked for portably at compile-time or
31    easily eliminated at run-time.
32
33    Define WRAPV to 1 if the assumption is valid.  Otherwise, define it
34    to 0; this forces the use of slower code that, while not guaranteed
35    by the C Standard, works on all production platforms that we know
36    about.  */
37 #ifndef WRAPV
38 # if (__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__
39 #  pragma GCC optimize ("wrapv")
40 #  define WRAPV 1
41 # else
42 #  define WRAPV 0
43 # endif
44 #endif
45
46 /* Assume that leap seconds are possible, unless told otherwise.
47    If the host has a `zic' command with a `-L leapsecondfilename' option,
48    then it supports leap seconds; otherwise it probably doesn't.  */
49 #ifndef LEAP_SECONDS_POSSIBLE
50 # define LEAP_SECONDS_POSSIBLE 1
51 #endif
52
53 #include <time.h>
54
55 #include <limits.h>
56
57 #include <string.h>             /* For the real memcpy prototype.  */
58
59 #if DEBUG
60 # include <stdio.h>
61 # include <stdlib.h>
62 /* Make it work even if the system's libc has its own mktime routine.  */
63 # define mktime my_mktime
64 #endif /* DEBUG */
65
66 /* A signed type that is at least one bit wider than int.  */
67 #if INT_MAX <= LONG_MAX / 2
68 typedef long int long_int;
69 #else
70 typedef long long int long_int;
71 #endif
72
73 /* Shift A right by B bits portably, by dividing A by 2**B and
74    truncating towards minus infinity.  A and B should be free of side
75    effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
76    INT_BITS is the number of useful bits in an int.  GNU code can
77    assume that INT_BITS is at least 32.
78
79    ISO C99 says that A >> B is implementation-defined if A < 0.  Some
80    implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
81    right in the usual way when A < 0, so SHR falls back on division if
82    ordinary A >> B doesn't seem to be the usual signed shift.  */
83 #define SHR(a, b)                                               \
84   ((-1 >> 1 == -1                                               \
85     && (long_int) -1 >> 1 == -1                                 \
86     && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t)))      \
87    ? (a) >> (b)                                                 \
88    : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
89
90 /* The extra casts in the following macros work around compiler bugs,
91    e.g., in Cray C 5.0.3.0.  */
92
93 /* True if the arithmetic type T is an integer type.  bool counts as
94    an integer.  */
95 #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
96
97 /* True if negative values of the signed integer type T use two's
98    complement, or if T is an unsigned integer type.  */
99 #define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
100
101 /* True if the arithmetic type T is signed.  */
102 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
103
104 /* The maximum and minimum values for the integer type T.  These
105    macros have undefined behavior if T is signed and has padding bits.
106    If this is a problem for you, please let us know how to fix it for
107    your host.  */
108 #define TYPE_MINIMUM(t) \
109   ((t) (! TYPE_SIGNED (t) \
110         ? (t) 0 \
111         : ~ TYPE_MAXIMUM (t)))
112 #define TYPE_MAXIMUM(t) \
113   ((t) (! TYPE_SIGNED (t) \
114         ? (t) -1 \
115         : (((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) << 1) + 1)))
116
117 #ifndef TIME_T_MIN
118 # define TIME_T_MIN TYPE_MINIMUM (time_t)
119 #endif
120 #ifndef TIME_T_MAX
121 # define TIME_T_MAX TYPE_MAXIMUM (time_t)
122 #endif
123 #define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
124
125 /* Verify a requirement at compile-time (unlike assert, which is runtime).  */
126 #define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
127
128 verify (time_t_is_integer, TYPE_IS_INTEGER (time_t));
129 verify (twos_complement_arithmetic,
130         (TYPE_TWOS_COMPLEMENT (int)
131          && TYPE_TWOS_COMPLEMENT (long_int)
132          && TYPE_TWOS_COMPLEMENT (time_t)));
133
134 #define EPOCH_YEAR 1970
135 #define TM_YEAR_BASE 1900
136 verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
137
138 /* Return 1 if YEAR + TM_YEAR_BASE is a leap year.  */
139 static inline int
140 leapyear (long_int year)
141 {
142   /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
143      Also, work even if YEAR is negative.  */
144   return
145     ((year & 3) == 0
146      && (year % 100 != 0
147          || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
148 }
149
150 /* How many days come before each month (0-12).  */
151 #ifndef _LIBC
152 static
153 #endif
154 const unsigned short int __mon_yday[2][13] =
155   {
156     /* Normal years.  */
157     { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
158     /* Leap years.  */
159     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
160   };
161
162
163 #ifndef _LIBC
164 /* Portable standalone applications should supply a <time.h> that
165    declares a POSIX-compliant localtime_r, for the benefit of older
166    implementations that lack localtime_r or have a nonstandard one.
167    See the gnulib time_r module for one way to implement this.  */
168 # undef __localtime_r
169 # define __localtime_r localtime_r
170 # define __mktime_internal mktime_internal
171 # include "mktime-internal.h"
172 #endif
173
174 /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
175    (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
176    were not adjusted between the time stamps.
177
178    The YEAR values uses the same numbering as TP->tm_year.  Values
179    need not be in the usual range.  However, YEAR1 must not be less
180    than 2 * INT_MIN or greater than 2 * INT_MAX.
181
182    The result may overflow.  It is the caller's responsibility to
183    detect overflow.  */
184
185 static inline time_t
186 ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
187             int year0, int yday0, int hour0, int min0, int sec0)
188 {
189   verify (C99_integer_division, -1 / 2 == 0);
190   verify (long_int_year_and_yday_are_wide_enough,
191           INT_MAX == INT_MAX * (long_int) 2 / 2);
192
193   /* Compute intervening leap days correctly even if year is negative.
194      Take care to avoid integer overflow here.  */
195   int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3);
196   int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3);
197   int a100 = a4 / 25 - (a4 % 25 < 0);
198   int b100 = b4 / 25 - (b4 % 25 < 0);
199   int a400 = SHR (a100, 2);
200   int b400 = SHR (b100, 2);
201   int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
202
203   /* Compute the desired time in time_t precision.  Overflow might
204      occur here.  */
205   time_t tyear1 = year1;
206   time_t years = tyear1 - year0;
207   time_t days = 365 * years + yday1 - yday0 + intervening_leap_days;
208   time_t hours = 24 * days + hour1 - hour0;
209   time_t minutes = 60 * hours + min1 - min0;
210   time_t seconds = 60 * minutes + sec1 - sec0;
211   return seconds;
212 }
213
214 /* Return the average of A and B, even if A + B would overflow.  */
215 static time_t
216 time_t_avg (time_t a, time_t b)
217 {
218   return SHR (a, 1) + SHR (b, 1) + (a & b & 1);
219 }
220
221 /* Return 1 if A + B does not overflow.  If time_t is unsigned and if
222    B's top bit is set, assume that the sum represents A - -B, and
223    return 1 if the subtraction does not wrap around.  */
224 static int
225 time_t_add_ok (time_t a, time_t b)
226 {
227   if (! TYPE_SIGNED (time_t))
228     {
229       time_t sum = a + b;
230       return (sum < a) == (TIME_T_MIDPOINT <= b);
231     }
232   else if (WRAPV)
233     {
234       time_t sum = a + b;
235       return (sum < a) == (b < 0);
236     }
237   else
238     {
239       time_t avg = time_t_avg (a, b);
240       return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
241     }
242 }
243
244 /* Return 1 if A + B does not overflow.  */
245 static int
246 time_t_int_add_ok (time_t a, int b)
247 {
248   verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX);
249   if (WRAPV)
250     {
251       time_t sum = a + b;
252       return (sum < a) == (b < 0);
253     }
254   else
255     {
256       int a_odd = a & 1;
257       time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b));
258       return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
259     }
260 }
261
262 /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
263    assuming that *T corresponds to *TP and that no clock adjustments
264    occurred between *TP and the desired time.
265    If TP is null, return a value not equal to *T; this avoids false matches.
266    If overflow occurs, yield the minimal or maximal value, except do not
267    yield a value equal to *T.  */
268 static time_t
269 guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
270                const time_t *t, const struct tm *tp)
271 {
272   if (tp)
273     {
274       time_t d = ydhms_diff (year, yday, hour, min, sec,
275                              tp->tm_year, tp->tm_yday,
276                              tp->tm_hour, tp->tm_min, tp->tm_sec);
277       if (time_t_add_ok (*t, d))
278         return *t + d;
279     }
280
281   /* Overflow occurred one way or another.  Return the nearest result
282      that is actually in range, except don't report a zero difference
283      if the actual difference is nonzero, as that would cause a false
284      match; and don't oscillate between two values, as that would
285      confuse the spring-forward gap detector.  */
286   return (*t < TIME_T_MIDPOINT
287           ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN)
288           : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX));
289 }
290
291 /* Use CONVERT to convert *T to a broken down time in *TP.
292    If *T is out of range for conversion, adjust it so that
293    it is the nearest in-range value and then convert that.  */
294 static struct tm *
295 ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
296                 time_t *t, struct tm *tp)
297 {
298   struct tm *r = convert (t, tp);
299
300   if (!r && *t)
301     {
302       time_t bad = *t;
303       time_t ok = 0;
304
305       /* BAD is a known unconvertible time_t, and OK is a known good one.
306          Use binary search to narrow the range between BAD and OK until
307          they differ by 1.  */
308       while (bad != ok + (bad < 0 ? -1 : 1))
309         {
310           time_t mid = *t = time_t_avg (ok, bad);
311           r = convert (t, tp);
312           if (r)
313             ok = mid;
314           else
315             bad = mid;
316         }
317
318       if (!r && ok)
319         {
320           /* The last conversion attempt failed;
321              revert to the most recent successful attempt.  */
322           *t = ok;
323           r = convert (t, tp);
324         }
325     }
326
327   return r;
328 }
329
330
331 /* Convert *TP to a time_t value, inverting
332    the monotonic and mostly-unit-linear conversion function CONVERT.
333    Use *OFFSET to keep track of a guess at the offset of the result,
334    compared to what the result would be for UTC without leap seconds.
335    If *OFFSET's guess is correct, only one CONVERT call is needed.
336    This function is external because it is used also by timegm.c.  */
337 time_t
338 __mktime_internal (struct tm *tp,
339                    struct tm *(*convert) (const time_t *, struct tm *),
340                    time_t *offset)
341 {
342   time_t t, gt, t0, t1, t2;
343   struct tm tm;
344
345   /* The maximum number of probes (calls to CONVERT) should be enough
346      to handle any combinations of time zone rule changes, solar time,
347      leap seconds, and oscillations around a spring-forward gap.
348      POSIX.1 prohibits leap seconds, but some hosts have them anyway.  */
349   int remaining_probes = 6;
350
351   /* Time requested.  Copy it in case CONVERT modifies *TP; this can
352      occur if TP is localtime's returned value and CONVERT is localtime.  */
353   int sec = tp->tm_sec;
354   int min = tp->tm_min;
355   int hour = tp->tm_hour;
356   int mday = tp->tm_mday;
357   int mon = tp->tm_mon;
358   int year_requested = tp->tm_year;
359   /* Normalize the value.  */
360   int isdst = ((tp->tm_isdst >> (8 * sizeof (tp->tm_isdst) - 1))
361                | (tp->tm_isdst != 0));
362
363   /* 1 if the previous probe was DST.  */
364   int dst2;
365
366   /* Ensure that mon is in range, and set year accordingly.  */
367   int mon_remainder = mon % 12;
368   int negative_mon_remainder = mon_remainder < 0;
369   int mon_years = mon / 12 - negative_mon_remainder;
370   long_int lyear_requested = year_requested;
371   long_int year = lyear_requested + mon_years;
372
373   /* The other values need not be in range:
374      the remaining code handles minor overflows correctly,
375      assuming int and time_t arithmetic wraps around.
376      Major overflows are caught at the end.  */
377
378   /* Calculate day of year from year, month, and day of month.
379      The result need not be in range.  */
380   int mon_yday = ((__mon_yday[leapyear (year)]
381                    [mon_remainder + 12 * negative_mon_remainder])
382                   - 1);
383   long_int lmday = mday;
384   long_int yday = mon_yday + lmday;
385
386   time_t guessed_offset = *offset;
387
388   int sec_requested = sec;
389
390   if (LEAP_SECONDS_POSSIBLE)
391     {
392       /* Handle out-of-range seconds specially,
393          since ydhms_tm_diff assumes every minute has 60 seconds.  */
394       if (sec < 0)
395         sec = 0;
396       if (59 < sec)
397         sec = 59;
398     }
399
400   /* Invert CONVERT by probing.  First assume the same offset as last
401      time.  */
402
403   t0 = ydhms_diff (year, yday, hour, min, sec,
404                    EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset);
405
406   if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
407     {
408       /* time_t isn't large enough to rule out overflows, so check
409          for major overflows.  A gross check suffices, since if t0
410          has overflowed, it is off by a multiple of TIME_T_MAX -
411          TIME_T_MIN + 1.  So ignore any component of the difference
412          that is bounded by a small value.  */
413
414       /* Approximate log base 2 of the number of time units per
415          biennium.  A biennium is 2 years; use this unit instead of
416          years to avoid integer overflow.  For example, 2 average
417          Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds,
418          which is 63113904 seconds, and rint (log2 (63113904)) is
419          26.  */
420       int ALOG2_SECONDS_PER_BIENNIUM = 26;
421       int ALOG2_MINUTES_PER_BIENNIUM = 20;
422       int ALOG2_HOURS_PER_BIENNIUM = 14;
423       int ALOG2_DAYS_PER_BIENNIUM = 10;
424       int LOG2_YEARS_PER_BIENNIUM = 1;
425
426       int approx_requested_biennia =
427         (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
428          - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
429          + SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
430          + SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
431          + SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
432          + (LEAP_SECONDS_POSSIBLE
433             ? 0
434             : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
435
436       int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
437       int diff = approx_biennia - approx_requested_biennia;
438       int abs_diff = diff < 0 ? -1 - diff : diff;
439
440       /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
441          gives a positive value of 715827882.  Setting a variable
442          first then doing math on it seems to work.
443          (ghazi@caip.rutgers.edu) */
444       time_t time_t_max = TIME_T_MAX;
445       time_t time_t_min = TIME_T_MIN;
446       time_t overflow_threshold =
447         (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
448
449       if (overflow_threshold < abs_diff)
450         {
451           /* Overflow occurred.  Try repairing it; this might work if
452              the time zone offset is enough to undo the overflow.  */
453           time_t repaired_t0 = -1 - t0;
454           approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
455           diff = approx_biennia - approx_requested_biennia;
456           abs_diff = diff < 0 ? -1 - diff : diff;
457           if (overflow_threshold < abs_diff)
458             return -1;
459           guessed_offset += repaired_t0 - t0;
460           t0 = repaired_t0;
461         }
462     }
463
464   /* Repeatedly use the error to improve the guess.  */
465
466   for (t = t1 = t2 = t0, dst2 = 0;
467        (gt = guess_time_tm (year, yday, hour, min, sec, &t,
468                             ranged_convert (convert, &t, &tm)),
469         t != gt);
470        t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0)
471     if (t == t1 && t != t2
472         && (tm.tm_isdst < 0
473             || (isdst < 0
474                 ? dst2 <= (tm.tm_isdst != 0)
475                 : (isdst != 0) != (tm.tm_isdst != 0))))
476       /* We can't possibly find a match, as we are oscillating
477          between two values.  The requested time probably falls
478          within a spring-forward gap of size GT - T.  Follow the common
479          practice in this case, which is to return a time that is GT - T
480          away from the requested time, preferring a time whose
481          tm_isdst differs from the requested value.  (If no tm_isdst
482          was requested and only one of the two values has a nonzero
483          tm_isdst, prefer that value.)  In practice, this is more
484          useful than returning -1.  */
485       goto offset_found;
486     else if (--remaining_probes == 0)
487       return -1;
488
489   /* We have a match.  Check whether tm.tm_isdst has the requested
490      value, if any.  */
491   if (isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst)
492     {
493       /* tm.tm_isdst has the wrong value.  Look for a neighboring
494          time with the right value, and use its UTC offset.
495
496          Heuristic: probe the adjacent timestamps in both directions,
497          looking for the desired isdst.  This should work for all real
498          time zone histories in the tz database.  */
499
500       /* Distance between probes when looking for a DST boundary.  In
501          tzdata2003a, the shortest period of DST is 601200 seconds
502          (e.g., America/Recife starting 2000-10-08 01:00), and the
503          shortest period of non-DST surrounded by DST is 694800
504          seconds (Africa/Tunis starting 1943-04-17 01:00).  Use the
505          minimum of these two values, so we don't miss these short
506          periods when probing.  */
507       int stride = 601200;
508
509       /* The longest period of DST in tzdata2003a is 536454000 seconds
510          (e.g., America/Jujuy starting 1946-10-01 01:00).  The longest
511          period of non-DST is much longer, but it makes no real sense
512          to search for more than a year of non-DST, so use the DST
513          max.  */
514       int duration_max = 536454000;
515
516       /* Search in both directions, so the maximum distance is half
517          the duration; add the stride to avoid off-by-1 problems.  */
518       int delta_bound = duration_max / 2 + stride;
519
520       int delta, direction;
521
522       for (delta = stride; delta < delta_bound; delta += stride)
523         for (direction = -1; direction <= 1; direction += 2)
524           if (time_t_int_add_ok (t, delta * direction))
525             {
526               time_t ot = t + delta * direction;
527               struct tm otm;
528               ranged_convert (convert, &ot, &otm);
529               if (otm.tm_isdst == isdst)
530                 {
531                   /* We found the desired tm_isdst.
532                      Extrapolate back to the desired time.  */
533                   t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
534                   ranged_convert (convert, &t, &tm);
535                   goto offset_found;
536                 }
537             }
538     }
539
540  offset_found:
541   *offset = guessed_offset + t - t0;
542
543   if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec)
544     {
545       /* Adjust time to reflect the tm_sec requested, not the normalized value.
546          Also, repair any damage from a false match due to a leap second.  */
547       int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec;
548       if (! time_t_int_add_ok (t, sec_requested))
549         return -1;
550       t1 = t + sec_requested;
551       if (! time_t_int_add_ok (t1, sec_adjustment))
552         return -1;
553       t2 = t1 + sec_adjustment;
554       if (! convert (&t2, &tm))
555         return -1;
556       t = t2;
557     }
558
559   *tp = tm;
560   return t;
561 }
562
563
564 /* FIXME: This should use a signed type wide enough to hold any UTC
565    offset in seconds.  'int' should be good enough for GNU code.  We
566    can't fix this unilaterally though, as other modules invoke
567    __mktime_internal.  */
568 static time_t localtime_offset;
569
570 /* Convert *TP to a time_t value.  */
571 time_t
572 mktime (struct tm *tp)
573 {
574 #ifdef _LIBC
575   /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
576      time zone names contained in the external variable `tzname' shall
577      be set as if the tzset() function had been called.  */
578   __tzset ();
579 #endif
580
581   return __mktime_internal (tp, __localtime_r, &localtime_offset);
582 }
583
584 #ifdef weak_alias
585 weak_alias (mktime, timelocal)
586 #endif
587
588 #ifdef _LIBC
589 libc_hidden_def (mktime)
590 libc_hidden_weak (timelocal)
591 #endif
592 \f
593 #if DEBUG
594
595 static int
596 not_equal_tm (const struct tm *a, const struct tm *b)
597 {
598   return ((a->tm_sec ^ b->tm_sec)
599           | (a->tm_min ^ b->tm_min)
600           | (a->tm_hour ^ b->tm_hour)
601           | (a->tm_mday ^ b->tm_mday)
602           | (a->tm_mon ^ b->tm_mon)
603           | (a->tm_year ^ b->tm_year)
604           | (a->tm_yday ^ b->tm_yday)
605           | (a->tm_isdst ^ b->tm_isdst));
606 }
607
608 static void
609 print_tm (const struct tm *tp)
610 {
611   if (tp)
612     printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
613             tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
614             tp->tm_hour, tp->tm_min, tp->tm_sec,
615             tp->tm_yday, tp->tm_wday, tp->tm_isdst);
616   else
617     printf ("0");
618 }
619
620 static int
621 check_result (time_t tk, struct tm tmk, time_t tl, const struct tm *lt)
622 {
623   if (tk != tl || !lt || not_equal_tm (&tmk, lt))
624     {
625       printf ("mktime (");
626       print_tm (lt);
627       printf (")\nyields (");
628       print_tm (&tmk);
629       printf (") == %ld, should be %ld\n", (long int) tk, (long int) tl);
630       return 1;
631     }
632
633   return 0;
634 }
635
636 int
637 main (int argc, char **argv)
638 {
639   int status = 0;
640   struct tm tm, tmk, tml;
641   struct tm *lt;
642   time_t tk, tl, tl1;
643   char trailer;
644
645   if ((argc == 3 || argc == 4)
646       && (sscanf (argv[1], "%d-%d-%d%c",
647                   &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
648           == 3)
649       && (sscanf (argv[2], "%d:%d:%d%c",
650                   &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
651           == 3))
652     {
653       tm.tm_year -= TM_YEAR_BASE;
654       tm.tm_mon--;
655       tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
656       tmk = tm;
657       tl = mktime (&tmk);
658       lt = localtime (&tl);
659       if (lt)
660         {
661           tml = *lt;
662           lt = &tml;
663         }
664       printf ("mktime returns %ld == ", (long int) tl);
665       print_tm (&tmk);
666       printf ("\n");
667       status = check_result (tl, tmk, tl, lt);
668     }
669   else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
670     {
671       time_t from = atol (argv[1]);
672       time_t by = atol (argv[2]);
673       time_t to = atol (argv[3]);
674
675       if (argc == 4)
676         for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
677           {
678             lt = localtime (&tl);
679             if (lt)
680               {
681                 tmk = tml = *lt;
682                 tk = mktime (&tmk);
683                 status |= check_result (tk, tmk, tl, &tml);
684               }
685             else
686               {
687                 printf ("localtime (%ld) yields 0\n", (long int) tl);
688                 status = 1;
689               }
690             tl1 = tl + by;
691             if ((tl1 < tl) != (by < 0))
692               break;
693           }
694       else
695         for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
696           {
697             /* Null benchmark.  */
698             lt = localtime (&tl);
699             if (lt)
700               {
701                 tmk = tml = *lt;
702                 tk = tl;
703                 status |= check_result (tk, tmk, tl, &tml);
704               }
705             else
706               {
707                 printf ("localtime (%ld) yields 0\n", (long int) tl);
708                 status = 1;
709               }
710             tl1 = tl + by;
711             if ((tl1 < tl) != (by < 0))
712               break;
713           }
714     }
715   else
716     printf ("Usage:\
717 \t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
718 \t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
719 \t%s FROM BY TO - # Do not test those values (for benchmark).\n",
720             argv[0], argv[0], argv[0]);
721
722   return status;
723 }
724
725 #endif /* DEBUG */
726 \f
727 /*
728 Local Variables:
729 compile-command: "gcc -DDEBUG -Wall -W -O2 -g mktime.c -o mktime"
730 End:
731 */