1
/* -*- buffer-read-only: t -*- vi: set ro: */
2
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3
/* Convert a `struct tm' to a time_t value.
4
Copyright (C) 1993-1999, 2002-2007, 2009-2011 Free Software Foundation, Inc.
1
/* Convert a 'struct tm' to a time_t value.
2
Copyright (C) 1993-2012 Free Software Foundation, Inc.
5
3
This file is part of the GNU C Library.
6
4
Contributed by Paul Eggert <eggert@twinsun.com>.
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3, or (at your option)
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.
13
This program is distributed in the hope that it will be useful,
11
The GNU C Library is distributed in the hope that it will be useful,
14
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
General Public License for more details.
18
You should have received a copy of the GNU General Public License along
19
with this program; if not, write to the Free Software Foundation,
20
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
16
You should have received a copy of the GNU General Public
17
License along with the GNU C Library; if not, see
18
<http://www.gnu.org/licenses/>. */
22
20
/* Define this to have a standalone program to test this implementation of
27
25
# include <config.h>
30
/* Some of the code in this file assumes that signed integer overflow
31
silently wraps around. This assumption can't easily be programmed
32
around, nor can it be checked for portably at compile-time or
33
easily eliminated at run-time.
35
Define WRAPV to 1 if the assumption is valid. Otherwise, define it
36
to 0; this forces the use of slower code that, while not guaranteed
37
by the C Standard, works on all production platforms that we know
40
# if (__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__
41
# pragma GCC optimize ("wrapv")
48
28
/* Assume that leap seconds are possible, unless told otherwise.
49
If the host has a `zic' command with a `-L leapsecondfilename' option,
29
If the host has a 'zic' command with a '-L leapsecondfilename' option,
50
30
then it supports leap seconds; otherwise it probably doesn't. */
51
31
#ifndef LEAP_SECONDS_POSSIBLE
52
32
# define LEAP_SECONDS_POSSIBLE 1
66
46
# define mktime my_mktime
49
/* Some of the code in this file assumes that signed integer overflow
50
silently wraps around. This assumption can't easily be programmed
51
around, nor can it be checked for portably at compile-time or
52
easily eliminated at run-time.
54
Define WRAPV to 1 if the assumption is valid and if
55
#pragma GCC optimize ("wrapv")
56
does not trigger GCC bug 51793
57
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51793>.
58
Otherwise, define it to 0; this forces the use of slower code that,
59
while not guaranteed by the C Standard, works on all production
60
platforms that we know about. */
62
# if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \
64
# pragma GCC optimize ("wrapv")
69
71
/* Verify a requirement at compile-time (unlike assert, which is runtime). */
70
72
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
277
279
yield a value equal to *T. */
279
281
guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
280
const time_t *t, const struct tm *tp)
282
const time_t *t, const struct tm *tp)
284
286
time_t d = ydhms_diff (year, yday, hour, min, sec,
285
tp->tm_year, tp->tm_yday,
286
tp->tm_hour, tp->tm_min, tp->tm_sec);
287
tp->tm_year, tp->tm_yday,
288
tp->tm_hour, tp->tm_min, tp->tm_sec);
287
289
if (time_t_add_ok (*t, d))
291
293
/* Overflow occurred one way or another. Return the nearest result
398
400
if (LEAP_SECONDS_POSSIBLE)
400
402
/* Handle out-of-range seconds specially,
401
since ydhms_tm_diff assumes every minute has 60 seconds. */
403
since ydhms_tm_diff assumes every minute has 60 seconds. */
408
410
/* Invert CONVERT by probing. First assume the same offset as last
411
413
t0 = ydhms_diff (year, yday, hour, min, sec,
412
EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset);
414
EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset);
414
416
if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
416
418
/* time_t isn't large enough to rule out overflows, so check
417
for major overflows. A gross check suffices, since if t0
418
has overflowed, it is off by a multiple of TIME_T_MAX -
419
TIME_T_MIN + 1. So ignore any component of the difference
420
that is bounded by a small value. */
419
for major overflows. A gross check suffices, since if t0
420
has overflowed, it is off by a multiple of TIME_T_MAX -
421
TIME_T_MIN + 1. So ignore any component of the difference
422
that is bounded by a small value. */
422
424
/* Approximate log base 2 of the number of time units per
423
biennium. A biennium is 2 years; use this unit instead of
424
years to avoid integer overflow. For example, 2 average
425
Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds,
426
which is 63113904 seconds, and rint (log2 (63113904)) is
425
biennium. A biennium is 2 years; use this unit instead of
426
years to avoid integer overflow. For example, 2 average
427
Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds,
428
which is 63113904 seconds, and rint (log2 (63113904)) is
428
430
int ALOG2_SECONDS_PER_BIENNIUM = 26;
429
431
int ALOG2_MINUTES_PER_BIENNIUM = 20;
430
432
int ALOG2_HOURS_PER_BIENNIUM = 14;
432
434
int LOG2_YEARS_PER_BIENNIUM = 1;
434
436
int approx_requested_biennia =
435
(SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
436
- SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
437
+ SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
438
+ SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
439
+ SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
440
+ (LEAP_SECONDS_POSSIBLE
442
: SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
437
(SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
438
- SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
439
+ SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
440
+ SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
441
+ SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
442
+ (LEAP_SECONDS_POSSIBLE
444
: SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
444
446
int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
445
447
int diff = approx_biennia - approx_requested_biennia;
446
int abs_diff = diff < 0 ? -1 - diff : diff;
448
int approx_abs_diff = diff < 0 ? -1 - diff : diff;
448
450
/* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
449
gives a positive value of 715827882. Setting a variable
450
first then doing math on it seems to work.
451
(ghazi@caip.rutgers.edu) */
451
gives a positive value of 715827882. Setting a variable
452
first then doing math on it seems to work.
453
(ghazi@caip.rutgers.edu) */
452
454
time_t time_t_max = TIME_T_MAX;
453
455
time_t time_t_min = TIME_T_MIN;
454
456
time_t overflow_threshold =
455
(time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
457
(time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
457
if (overflow_threshold < abs_diff)
459
/* Overflow occurred. Try repairing it; this might work if
460
the time zone offset is enough to undo the overflow. */
461
time_t repaired_t0 = -1 - t0;
462
approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
463
diff = approx_biennia - approx_requested_biennia;
464
abs_diff = diff < 0 ? -1 - diff : diff;
465
if (overflow_threshold < abs_diff)
467
guessed_offset += repaired_t0 - t0;
459
if (overflow_threshold < approx_abs_diff)
461
/* Overflow occurred. Try repairing it; this might work if
462
the time zone offset is enough to undo the overflow. */
463
time_t repaired_t0 = -1 - t0;
464
approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
465
diff = approx_biennia - approx_requested_biennia;
466
approx_abs_diff = diff < 0 ? -1 - diff : diff;
467
if (overflow_threshold < approx_abs_diff)
469
guessed_offset += repaired_t0 - t0;
472
474
/* Repeatedly use the error to improve the guess. */
474
476
for (t = t1 = t2 = t0, dst2 = 0;
475
477
(gt = guess_time_tm (year, yday, hour, min, sec, &t,
476
ranged_convert (convert, &t, &tm)),
478
ranged_convert (convert, &t, &tm)),
478
480
t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0)
479
481
if (t == t1 && t != t2
482
? dst2 <= (tm.tm_isdst != 0)
483
: (isdst != 0) != (tm.tm_isdst != 0))))
484
? dst2 <= (tm.tm_isdst != 0)
485
: (isdst != 0) != (tm.tm_isdst != 0))))
484
486
/* We can't possibly find a match, as we are oscillating
485
between two values. The requested time probably falls
486
within a spring-forward gap of size GT - T. Follow the common
487
practice in this case, which is to return a time that is GT - T
488
away from the requested time, preferring a time whose
489
tm_isdst differs from the requested value. (If no tm_isdst
490
was requested and only one of the two values has a nonzero
491
tm_isdst, prefer that value.) In practice, this is more
492
useful than returning -1. */
487
between two values. The requested time probably falls
488
within a spring-forward gap of size GT - T. Follow the common
489
practice in this case, which is to return a time that is GT - T
490
away from the requested time, preferring a time whose
491
tm_isdst differs from the requested value. (If no tm_isdst
492
was requested and only one of the two values has a nonzero
493
tm_isdst, prefer that value.) In practice, this is more
494
useful than returning -1. */
493
495
goto offset_found;
494
496
else if (--remaining_probes == 0)
499
501
if (isdst_differ (isdst, tm.tm_isdst))
501
503
/* tm.tm_isdst has the wrong value. Look for a neighboring
502
time with the right value, and use its UTC offset.
504
time with the right value, and use its UTC offset.
504
Heuristic: probe the adjacent timestamps in both directions,
505
looking for the desired isdst. This should work for all real
506
time zone histories in the tz database. */
506
Heuristic: probe the adjacent timestamps in both directions,
507
looking for the desired isdst. This should work for all real
508
time zone histories in the tz database. */
508
510
/* Distance between probes when looking for a DST boundary. In
509
tzdata2003a, the shortest period of DST is 601200 seconds
510
(e.g., America/Recife starting 2000-10-08 01:00), and the
511
shortest period of non-DST surrounded by DST is 694800
512
seconds (Africa/Tunis starting 1943-04-17 01:00). Use the
513
minimum of these two values, so we don't miss these short
514
periods when probing. */
511
tzdata2003a, the shortest period of DST is 601200 seconds
512
(e.g., America/Recife starting 2000-10-08 01:00), and the
513
shortest period of non-DST surrounded by DST is 694800
514
seconds (Africa/Tunis starting 1943-04-17 01:00). Use the
515
minimum of these two values, so we don't miss these short
516
periods when probing. */
515
517
int stride = 601200;
517
519
/* The longest period of DST in tzdata2003a is 536454000 seconds
518
(e.g., America/Jujuy starting 1946-10-01 01:00). The longest
519
period of non-DST is much longer, but it makes no real sense
520
to search for more than a year of non-DST, so use the DST
520
(e.g., America/Jujuy starting 1946-10-01 01:00). The longest
521
period of non-DST is much longer, but it makes no real sense
522
to search for more than a year of non-DST, so use the DST
522
524
int duration_max = 536454000;
524
526
/* Search in both directions, so the maximum distance is half
525
the duration; add the stride to avoid off-by-1 problems. */
527
the duration; add the stride to avoid off-by-1 problems. */
526
528
int delta_bound = duration_max / 2 + stride;
528
530
int delta, direction;
530
532
for (delta = stride; delta < delta_bound; delta += stride)
531
for (direction = -1; direction <= 1; direction += 2)
532
if (time_t_int_add_ok (t, delta * direction))
534
time_t ot = t + delta * direction;
536
ranged_convert (convert, &ot, &otm);
537
if (! isdst_differ (isdst, otm.tm_isdst))
539
/* We found the desired tm_isdst.
540
Extrapolate back to the desired time. */
541
t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
542
ranged_convert (convert, &t, &tm);
533
for (direction = -1; direction <= 1; direction += 2)
534
if (time_t_int_add_ok (t, delta * direction))
536
time_t ot = t + delta * direction;
538
ranged_convert (convert, &ot, &otm);
539
if (! isdst_differ (isdst, otm.tm_isdst))
541
/* We found the desired tm_isdst.
542
Extrapolate back to the desired time. */
543
t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
544
ranged_convert (convert, &t, &tm);
604
606
not_equal_tm (const struct tm *a, const struct tm *b)
606
608
return ((a->tm_sec ^ b->tm_sec)
607
| (a->tm_min ^ b->tm_min)
608
| (a->tm_hour ^ b->tm_hour)
609
| (a->tm_mday ^ b->tm_mday)
610
| (a->tm_mon ^ b->tm_mon)
611
| (a->tm_year ^ b->tm_year)
612
| (a->tm_yday ^ b->tm_yday)
613
| isdst_differ (a->tm_isdst, b->tm_isdst));
609
| (a->tm_min ^ b->tm_min)
610
| (a->tm_hour ^ b->tm_hour)
611
| (a->tm_mday ^ b->tm_mday)
612
| (a->tm_mon ^ b->tm_mon)
613
| (a->tm_year ^ b->tm_year)
614
| (a->tm_yday ^ b->tm_yday)
615
| isdst_differ (a->tm_isdst, b->tm_isdst));
681
683
time_t to = atol (argv[3]);
684
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
686
lt = localtime (&tl);
691
status |= check_result (tk, tmk, tl, &tml);
695
printf ("localtime (%ld) yields 0\n", (long int) tl);
699
if ((tl1 < tl) != (by < 0))
686
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
688
lt = localtime (&tl);
693
status |= check_result (tk, tmk, tl, &tml);
697
printf ("localtime (%ld) yields 0\n", (long int) tl);
701
if ((tl1 < tl) != (by < 0))
703
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
705
/* Null benchmark. */
706
lt = localtime (&tl);
711
status |= check_result (tk, tmk, tl, &tml);
715
printf ("localtime (%ld) yields 0\n", (long int) tl);
719
if ((tl1 < tl) != (by < 0))
705
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
707
/* Null benchmark. */
708
lt = localtime (&tl);
713
status |= check_result (tk, tmk, tl, &tml);
717
printf ("localtime (%ld) yields 0\n", (long int) tl);
721
if ((tl1 < tl) != (by < 0))
725
727
\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
726
728
\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
727
729
\t%s FROM BY TO - # Do not test those values (for benchmark).\n",
728
argv[0], argv[0], argv[0]);
730
argv[0], argv[0], argv[0]);