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