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