Output alists with dotted pair notation in .dir-locals.el
[emacs.git] / lib / mktime.c
blob6953e984e5d2cb859f934dcd4001abbd3ead124d
1 /* Convert a 'struct tm' to a time_t value.
2 Copyright (C) 1993-2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Paul Eggert <eggert@twinsun.com>.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public
8 License as published by the Free Software Foundation; either
9 version 3 of the License, or (at your option) any later version.
11 The GNU C Library 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 GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
20 /* Define this to 1 to have a standalone program to test this implementation of
21 mktime. */
22 #ifndef DEBUG_MKTIME
23 # define DEBUG_MKTIME 0
24 #endif
26 /* The following macros influence what gets defined when this file is compiled:
28 Macro/expression Which gnulib module This compilation unit
29 should define
31 _LIBC (glibc proper) mktime
33 NEED_MKTIME_WORKING mktime rpl_mktime
34 || NEED_MKTIME_WINDOWS
36 NEED_MKTIME_INTERNAL mktime-internal mktime_internal
38 DEBUG_MKTIME (defined manually) my_mktime, main
41 #if !defined _LIBC && !DEBUG_MKTIME
42 # include <config.h>
43 #endif
45 /* Assume that leap seconds are possible, unless told otherwise.
46 If the host has a 'zic' command with a '-L leapsecondfilename' option,
47 then it supports leap seconds; otherwise it probably doesn't. */
48 #ifndef LEAP_SECONDS_POSSIBLE
49 # define LEAP_SECONDS_POSSIBLE 1
50 #endif
52 #include <time.h>
54 #include <limits.h>
55 #include <stdbool.h>
56 #include <stdlib.h>
57 #include <string.h>
59 #include <intprops.h>
60 #include <verify.h>
62 #if DEBUG_MKTIME
63 # include <stdio.h>
64 /* Make it work even if the system's libc has its own mktime routine. */
65 # undef mktime
66 # define mktime my_mktime
67 #endif /* DEBUG_MKTIME */
69 #ifndef NEED_MKTIME_INTERNAL
70 # define NEED_MKTIME_INTERNAL 0
71 #endif
72 #ifndef NEED_MKTIME_WINDOWS
73 # define NEED_MKTIME_WINDOWS 0
74 #endif
75 #ifndef NEED_MKTIME_WORKING
76 # define NEED_MKTIME_WORKING DEBUG_MKTIME
77 #endif
79 #include "mktime-internal.h"
81 #ifndef _LIBC
82 static void
83 my_tzset (void)
85 # if NEED_MKTIME_WINDOWS
86 /* Rectify the value of the environment variable TZ.
87 There are four possible kinds of such values:
88 - Traditional US time zone names, e.g. "PST8PDT". Syntax: see
89 <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
90 - Time zone names based on geography, that contain one or more
91 slashes, e.g. "Europe/Moscow".
92 - Time zone names based on geography, without slashes, e.g.
93 "Singapore".
94 - Time zone names that contain explicit DST rules. Syntax: see
95 <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
96 The Microsoft CRT understands only the first kind. It produces incorrect
97 results if the value of TZ is of the other kinds.
98 But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
99 of the second kind for most geographies, or of the first kind in a few
100 other geographies. If it is of the second kind, neutralize it. For the
101 Microsoft CRT, an absent or empty TZ means the time zone that the user
102 has set in the Windows Control Panel.
103 If the value of TZ is of the third or fourth kind -- Cygwin programs
104 understand these syntaxes as well --, it does not matter whether we
105 neutralize it or not, since these values occur only when a Cygwin user
106 has set TZ explicitly; this case is 1. rare and 2. under the user's
107 responsibility. */
108 const char *tz = getenv ("TZ");
109 if (tz != NULL && strchr (tz, '/') != NULL)
110 _putenv ("TZ=");
111 # elif HAVE_TZSET
112 tzset ();
113 # endif
115 # undef __tzset
116 # define __tzset() my_tzset ()
117 #endif
119 #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL
121 /* A signed type that can represent an integer number of years
122 multiplied by three times the number of seconds in a year. It is
123 needed when converting a tm_year value times the number of seconds
124 in a year. The factor of three comes because these products need
125 to be subtracted from each other, and sometimes with an offset
126 added to them, without worrying about overflow.
128 Much of the code uses long_int to represent time_t values, to
129 lessen the hassle of dealing with platforms where time_t is
130 unsigned, and because long_int should suffice to represent all
131 time_t values that mktime can generate even on platforms where
132 time_t is excessively wide. */
134 #if INT_MAX <= LONG_MAX / 3 / 366 / 24 / 60 / 60
135 typedef long int long_int;
136 #else
137 typedef long long int long_int;
138 #endif
139 verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 3 / 366 / 24 / 60 / 60);
141 /* Shift A right by B bits portably, by dividing A by 2**B and
142 truncating towards minus infinity. B should be in the range 0 <= B
143 <= LONG_INT_BITS - 2, where LONG_INT_BITS is the number of useful
144 bits in a long_int. LONG_INT_BITS is at least 32.
146 ISO C99 says that A >> B is implementation-defined if A < 0. Some
147 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
148 right in the usual way when A < 0, so SHR falls back on division if
149 ordinary A >> B doesn't seem to be the usual signed shift. */
151 static long_int
152 shr (long_int a, int b)
154 long_int one = 1;
155 return (-one >> 1 == -1
156 ? a >> b
157 : a / (one << b) - (a % (one << b) < 0));
160 /* Bounds for the intersection of time_t and long_int. */
162 static long_int const mktime_min
163 = ((TYPE_SIGNED (time_t) && TYPE_MINIMUM (time_t) < TYPE_MINIMUM (long_int))
164 ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (time_t));
165 static long_int const mktime_max
166 = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (time_t)
167 ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (time_t));
169 verify (TYPE_IS_INTEGER (time_t));
171 #define EPOCH_YEAR 1970
172 #define TM_YEAR_BASE 1900
173 verify (TM_YEAR_BASE % 100 == 0);
175 /* Is YEAR + TM_YEAR_BASE a leap year? */
176 static bool
177 leapyear (long_int year)
179 /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
180 Also, work even if YEAR is negative. */
181 return
182 ((year & 3) == 0
183 && (year % 100 != 0
184 || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
187 /* How many days come before each month (0-12). */
188 #ifndef _LIBC
189 static
190 #endif
191 const unsigned short int __mon_yday[2][13] =
193 /* Normal years. */
194 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
195 /* Leap years. */
196 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
200 /* Do the values A and B differ according to the rules for tm_isdst?
201 A and B differ if one is zero and the other positive. */
202 static bool
203 isdst_differ (int a, int b)
205 return (!a != !b) && (0 <= a) && (0 <= b);
208 /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
209 (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
210 were not adjusted between the timestamps.
212 The YEAR values uses the same numbering as TP->tm_year. Values
213 need not be in the usual range. However, YEAR1 must not overflow
214 when multiplied by three times the number of seconds in a year, and
215 likewise for YDAY1 and three times the number of seconds in a day. */
217 static long_int
218 ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
219 int year0, int yday0, int hour0, int min0, int sec0)
221 verify (-1 / 2 == 0);
223 /* Compute intervening leap days correctly even if year is negative.
224 Take care to avoid integer overflow here. */
225 int a4 = shr (year1, 2) + shr (TM_YEAR_BASE, 2) - ! (year1 & 3);
226 int b4 = shr (year0, 2) + shr (TM_YEAR_BASE, 2) - ! (year0 & 3);
227 int a100 = a4 / 25 - (a4 % 25 < 0);
228 int b100 = b4 / 25 - (b4 % 25 < 0);
229 int a400 = shr (a100, 2);
230 int b400 = shr (b100, 2);
231 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
233 /* Compute the desired time without overflowing. */
234 long_int years = year1 - year0;
235 long_int days = 365 * years + yday1 - yday0 + intervening_leap_days;
236 long_int hours = 24 * days + hour1 - hour0;
237 long_int minutes = 60 * hours + min1 - min0;
238 long_int seconds = 60 * minutes + sec1 - sec0;
239 return seconds;
242 /* Return the average of A and B, even if A + B would overflow.
243 Round toward positive infinity. */
244 static long_int
245 long_int_avg (long_int a, long_int b)
247 return shr (a, 1) + shr (b, 1) + ((a | b) & 1);
250 /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
251 assuming that T corresponds to *TP and that no clock adjustments
252 occurred between *TP and the desired time.
253 Although T and the returned value are of type long_int,
254 they represent time_t values and must be in time_t range.
255 If TP is null, return a value not equal to T; this avoids false matches.
256 YEAR and YDAY must not be so large that multiplying them by three times the
257 number of seconds in a year (or day, respectively) would overflow long_int.
258 If the returned value would be out of range, yield the minimal or
259 maximal in-range value, except do not yield a value equal to T. */
260 static long_int
261 guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
262 long_int t, const struct tm *tp)
264 if (tp)
266 long_int result;
267 long_int d = ydhms_diff (year, yday, hour, min, sec,
268 tp->tm_year, tp->tm_yday,
269 tp->tm_hour, tp->tm_min, tp->tm_sec);
270 if (! INT_ADD_WRAPV (t, d, &result))
271 return result;
274 /* Overflow occurred one way or another. Return the nearest result
275 that is actually in range, except don't report a zero difference
276 if the actual difference is nonzero, as that would cause a false
277 match; and don't oscillate between two values, as that would
278 confuse the spring-forward gap detector. */
279 return (t < long_int_avg (mktime_min, mktime_max)
280 ? (t <= mktime_min + 1 ? t + 1 : mktime_min)
281 : (mktime_max - 1 <= t ? t - 1 : mktime_max));
284 /* Use CONVERT to convert T to a struct tm value in *TM. T must be in
285 range for time_t. Return TM if successful, NULL if T is out of
286 range for CONVERT. */
287 static struct tm *
288 convert_time (struct tm *(*convert) (const time_t *, struct tm *),
289 long_int t, struct tm *tm)
291 time_t x = t;
292 return convert (&x, tm);
295 /* Use CONVERT to convert *T to a broken down time in *TP.
296 If *T is out of range for conversion, adjust it so that
297 it is the nearest in-range value and then convert that.
298 A value is in range if it fits in both time_t and long_int. */
299 static struct tm *
300 ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
301 long_int *t, struct tm *tp)
303 struct tm *r;
304 if (*t < mktime_min)
305 *t = mktime_min;
306 else if (mktime_max < *t)
307 *t = mktime_max;
308 r = convert_time (convert, *t, tp);
310 if (!r && *t)
312 long_int bad = *t;
313 long_int ok = 0;
315 /* BAD is a known unconvertible value, and OK is a known good one.
316 Use binary search to narrow the range between BAD and OK until
317 they differ by 1. */
318 while (true)
320 long_int mid = long_int_avg (ok, bad);
321 if (mid != ok && mid != bad)
322 break;
323 r = convert_time (convert, mid, tp);
324 if (r)
325 ok = mid;
326 else
327 bad = mid;
330 if (!r && ok)
332 /* The last conversion attempt failed;
333 revert to the most recent successful attempt. */
334 r = convert_time (convert, ok, tp);
338 return r;
342 /* Convert *TP to a time_t value, inverting
343 the monotonic and mostly-unit-linear conversion function CONVERT.
344 Use *OFFSET to keep track of a guess at the offset of the result,
345 compared to what the result would be for UTC without leap seconds.
346 If *OFFSET's guess is correct, only one CONVERT call is needed.
347 This function is external because it is used also by timegm.c. */
348 time_t
349 __mktime_internal (struct tm *tp,
350 struct tm *(*convert) (const time_t *, struct tm *),
351 mktime_offset_t *offset)
353 long_int t, gt, t0, t1, t2, dt;
354 struct tm tm;
356 /* The maximum number of probes (calls to CONVERT) should be enough
357 to handle any combinations of time zone rule changes, solar time,
358 leap seconds, and oscillations around a spring-forward gap.
359 POSIX.1 prohibits leap seconds, but some hosts have them anyway. */
360 int remaining_probes = 6;
362 /* Time requested. Copy it in case CONVERT modifies *TP; this can
363 occur if TP is localtime's returned value and CONVERT is localtime. */
364 int sec = tp->tm_sec;
365 int min = tp->tm_min;
366 int hour = tp->tm_hour;
367 int mday = tp->tm_mday;
368 int mon = tp->tm_mon;
369 int year_requested = tp->tm_year;
370 int isdst = tp->tm_isdst;
372 /* 1 if the previous probe was DST. */
373 int dst2;
375 /* Ensure that mon is in range, and set year accordingly. */
376 int mon_remainder = mon % 12;
377 int negative_mon_remainder = mon_remainder < 0;
378 int mon_years = mon / 12 - negative_mon_remainder;
379 long_int lyear_requested = year_requested;
380 long_int year = lyear_requested + mon_years;
382 /* The other values need not be in range:
383 the remaining code handles overflows correctly. */
385 /* Calculate day of year from year, month, and day of month.
386 The result need not be in range. */
387 int mon_yday = ((__mon_yday[leapyear (year)]
388 [mon_remainder + 12 * negative_mon_remainder])
389 - 1);
390 long_int lmday = mday;
391 long_int yday = mon_yday + lmday;
393 mktime_offset_t off = *offset;
394 int negative_offset_guess;
396 int sec_requested = sec;
398 if (LEAP_SECONDS_POSSIBLE)
400 /* Handle out-of-range seconds specially,
401 since ydhms_tm_diff assumes every minute has 60 seconds. */
402 if (sec < 0)
403 sec = 0;
404 if (59 < sec)
405 sec = 59;
408 /* Invert CONVERT by probing. First assume the same offset as last
409 time. */
411 INT_SUBTRACT_WRAPV (0, off, &negative_offset_guess);
412 t0 = ydhms_diff (year, yday, hour, min, sec,
413 EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, negative_offset_guess);
415 /* Repeatedly use the error to improve the guess. */
417 for (t = t1 = t2 = t0, dst2 = 0;
418 (gt = guess_time_tm (year, yday, hour, min, sec, t,
419 ranged_convert (convert, &t, &tm)),
420 t != gt);
421 t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0)
422 if (t == t1 && t != t2
423 && (tm.tm_isdst < 0
424 || (isdst < 0
425 ? dst2 <= (tm.tm_isdst != 0)
426 : (isdst != 0) != (tm.tm_isdst != 0))))
427 /* We can't possibly find a match, as we are oscillating
428 between two values. The requested time probably falls
429 within a spring-forward gap of size GT - T. Follow the common
430 practice in this case, which is to return a time that is GT - T
431 away from the requested time, preferring a time whose
432 tm_isdst differs from the requested value. (If no tm_isdst
433 was requested and only one of the two values has a nonzero
434 tm_isdst, prefer that value.) In practice, this is more
435 useful than returning -1. */
436 goto offset_found;
437 else if (--remaining_probes == 0)
438 return -1;
440 /* We have a match. Check whether tm.tm_isdst has the requested
441 value, if any. */
442 if (isdst_differ (isdst, tm.tm_isdst))
444 /* tm.tm_isdst has the wrong value. Look for a neighboring
445 time with the right value, and use its UTC offset.
447 Heuristic: probe the adjacent timestamps in both directions,
448 looking for the desired isdst. This should work for all real
449 time zone histories in the tz database. */
451 /* Distance between probes when looking for a DST boundary. In
452 tzdata2003a, the shortest period of DST is 601200 seconds
453 (e.g., America/Recife starting 2000-10-08 01:00), and the
454 shortest period of non-DST surrounded by DST is 694800
455 seconds (Africa/Tunis starting 1943-04-17 01:00). Use the
456 minimum of these two values, so we don't miss these short
457 periods when probing. */
458 int stride = 601200;
460 /* The longest period of DST in tzdata2003a is 536454000 seconds
461 (e.g., America/Jujuy starting 1946-10-01 01:00). The longest
462 period of non-DST is much longer, but it makes no real sense
463 to search for more than a year of non-DST, so use the DST
464 max. */
465 int duration_max = 536454000;
467 /* Search in both directions, so the maximum distance is half
468 the duration; add the stride to avoid off-by-1 problems. */
469 int delta_bound = duration_max / 2 + stride;
471 int delta, direction;
473 for (delta = stride; delta < delta_bound; delta += stride)
474 for (direction = -1; direction <= 1; direction += 2)
476 long_int ot;
477 if (! INT_ADD_WRAPV (t, delta * direction, &ot))
479 struct tm otm;
480 ranged_convert (convert, &ot, &otm);
481 if (! isdst_differ (isdst, otm.tm_isdst))
483 /* We found the desired tm_isdst.
484 Extrapolate back to the desired time. */
485 t = guess_time_tm (year, yday, hour, min, sec, ot, &otm);
486 ranged_convert (convert, &t, &tm);
487 goto offset_found;
493 offset_found:
494 /* Set *OFFSET to the low-order bits of T - T0 - NEGATIVE_OFFSET_GUESS.
495 This is just a heuristic to speed up the next mktime call, and
496 correctness is unaffected if integer overflow occurs here. */
497 INT_SUBTRACT_WRAPV (t, t0, &dt);
498 INT_SUBTRACT_WRAPV (dt, negative_offset_guess, offset);
500 if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec)
502 /* Adjust time to reflect the tm_sec requested, not the normalized value.
503 Also, repair any damage from a false match due to a leap second. */
504 long_int sec_adjustment = sec == 0 && tm.tm_sec == 60;
505 sec_adjustment -= sec;
506 sec_adjustment += sec_requested;
507 if (INT_ADD_WRAPV (t, sec_adjustment, &t)
508 || ! (mktime_min <= t && t <= mktime_max)
509 || ! convert_time (convert, t, &tm))
510 return -1;
513 *tp = tm;
514 return t;
517 #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL */
519 #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS
521 /* Convert *TP to a time_t value. */
522 time_t
523 mktime (struct tm *tp)
525 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
526 time zone names contained in the external variable 'tzname' shall
527 be set as if the tzset() function had been called. */
528 __tzset ();
530 # if defined __LIBC || NEED_MKTIME_WORKING
531 static mktime_offset_t localtime_offset;
532 return __mktime_internal (tp, __localtime_r, &localtime_offset);
533 # else
534 # undef mktime
535 return mktime (tp);
536 # endif
538 #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
540 #ifdef weak_alias
541 weak_alias (mktime, timelocal)
542 #endif
544 #ifdef _LIBC
545 libc_hidden_def (mktime)
546 libc_hidden_weak (timelocal)
547 #endif
549 #if DEBUG_MKTIME
551 static int
552 not_equal_tm (const struct tm *a, const struct tm *b)
554 return ((a->tm_sec ^ b->tm_sec)
555 | (a->tm_min ^ b->tm_min)
556 | (a->tm_hour ^ b->tm_hour)
557 | (a->tm_mday ^ b->tm_mday)
558 | (a->tm_mon ^ b->tm_mon)
559 | (a->tm_year ^ b->tm_year)
560 | (a->tm_yday ^ b->tm_yday)
561 | isdst_differ (a->tm_isdst, b->tm_isdst));
564 static void
565 print_tm (const struct tm *tp)
567 if (tp)
568 printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
569 tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
570 tp->tm_hour, tp->tm_min, tp->tm_sec,
571 tp->tm_yday, tp->tm_wday, tp->tm_isdst);
572 else
573 printf ("0");
576 static int
577 check_result (time_t tk, struct tm tmk, time_t tl, const struct tm *lt)
579 if (tk != tl || !lt || not_equal_tm (&tmk, lt))
581 printf ("mktime (");
582 print_tm (lt);
583 printf (")\nyields (");
584 print_tm (&tmk);
585 printf (") == %ld, should be %ld\n", (long int) tk, (long int) tl);
586 return 1;
589 return 0;
593 main (int argc, char **argv)
595 int status = 0;
596 struct tm tm, tmk, tml;
597 struct tm *lt;
598 time_t tk, tl, tl1;
599 char trailer;
601 /* Sanity check, plus call tzset. */
602 tl = 0;
603 if (! localtime (&tl))
605 printf ("localtime (0) fails\n");
606 status = 1;
609 if ((argc == 3 || argc == 4)
610 && (sscanf (argv[1], "%d-%d-%d%c",
611 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
612 == 3)
613 && (sscanf (argv[2], "%d:%d:%d%c",
614 &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
615 == 3))
617 tm.tm_year -= TM_YEAR_BASE;
618 tm.tm_mon--;
619 tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
620 tmk = tm;
621 tl = mktime (&tmk);
622 lt = localtime_r (&tl, &tml);
623 printf ("mktime returns %ld == ", (long int) tl);
624 print_tm (&tmk);
625 printf ("\n");
626 status = check_result (tl, tmk, tl, lt);
628 else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
630 time_t from = atol (argv[1]);
631 time_t by = atol (argv[2]);
632 time_t to = atol (argv[3]);
634 if (argc == 4)
635 for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
637 lt = localtime_r (&tl, &tml);
638 if (lt)
640 tmk = tml;
641 tk = mktime (&tmk);
642 status |= check_result (tk, tmk, tl, &tml);
644 else
646 printf ("localtime_r (%ld) yields 0\n", (long int) tl);
647 status = 1;
649 tl1 = tl + by;
650 if ((tl1 < tl) != (by < 0))
651 break;
653 else
654 for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
656 /* Null benchmark. */
657 lt = localtime_r (&tl, &tml);
658 if (lt)
660 tmk = tml;
661 tk = tl;
662 status |= check_result (tk, tmk, tl, &tml);
664 else
666 printf ("localtime_r (%ld) yields 0\n", (long int) tl);
667 status = 1;
669 tl1 = tl + by;
670 if ((tl1 < tl) != (by < 0))
671 break;
674 else
675 printf ("Usage:\
676 \t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
677 \t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
678 \t%s FROM BY TO - # Do not test those values (for benchmark).\n",
679 argv[0], argv[0], argv[0]);
681 return status;
684 #endif /* DEBUG_MKTIME */
687 Local Variables:
688 compile-command: "gcc -DDEBUG_MKTIME -I. -Wall -W -O2 -g mktime.c -o mktime"
689 End: