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