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