1
0
mirror of https://frontier.innolan.net/rainlance/amiga-tz.git synced 2026-05-06 16:58:22 +00:00

zic: work around GNOME bug by refusing to go back before the Big Bang

This works around Gnome bug 730332
<https://bugzilla.gnome.org/show_bug.cgi?id=730332>.
zic 2014c introduced the idea of generating a transition at the
minimum time value -2**63, to avoid ambiguities about what to do
before the first real transition.  Through Glib release 2.40, the
interval_end function of Glib's gtimezone.c subtracts one from
this, to find the end time of the zeroth interval (i.e., the
interval containing all the "early" time stamps); this subtraction
typically overflows and wraps around to 2**63 - 1, which causes
Glib to go off the rails and assume that all time stamps are
"early".  For example, Glib computes Sao Paulo time stamps as if
Brazil's circa-1913 rules were still in effect.
(Thanks to Leonardo Chiquitto for reporting the bug.)
Work around the bug by not generating time stamps equal to -2**63.
Come to think of it, time stamps before the Big Bang are physically
suspect anyway, so don't generate time stamps before the Big Bang.
* Makefile (GCC_DEBUG_FLAGS): Add comment re BIG_BANG.
* NEWS, zic.8 (NOTES): Document this.
* zic.c (BIG_BANG): New macro.
(big_bang_time): New constant.
(writezone, outzone, addtt): Compare to big_bang_time, not to
min_time, when deciding whether to output a time stamp.
This commit is contained in:
Paul Eggert
2014-05-23 22:56:18 -03:00
parent 9dc32cd094
commit b22d459a36
4 changed files with 50 additions and 6 deletions

View File

@@ -100,6 +100,7 @@ YEARISTYPE= ./yearistype
LDLIBS=
# Add the following to the end of the "CFLAGS=" line as needed.
# -DBIG_BANG=-9999999LL if the Big Bang occurred at time -9999999 (see zic.c)
# -DHAVE_ADJTIME=0 if `adjtime' does not exist (SVR0?)
# -DHAVE_DOS_FILE_NAMES if file names have drive specifiers etc. (MS-DOS)
# -DHAVE_GETTEXT=1 if `gettext' works (GNU, Linux, Solaris); also see LDLIBS

9
NEWS
View File

@@ -1,6 +1,15 @@
News for the tz database
Unreleased, experimental changes
Changes affecting code
zic no longer generates files containing time stamps before the Big Bang.
This works around GNOME bug 730332
<https://bugzilla.gnome.org/show_bug.cgi?id=730332>.
Release 2014c - 2014-05-13 07:44:13 -0700
Changes affecting near-future time stamps

6
zic.8
View File

@@ -519,6 +519,12 @@ produces a single transition to daylight saving at the new UT offset
To get separate transitions
use multiple zone continuation lines
specifying transition instants using universal time.
.PP
Time stamps before the Big Bang are silently omitted from the output.
This works around bugs in software that mishandles large negative time
stamps. Call it sour grapes, but pre-Big-Bang time stamps are
physically suspect anyway. The estimated time of the Big Bang is
approximate and may change in future versions.
.SH FILE
/usr/local/etc/zoneinfo standard directory used for created files
.SH "SEE ALSO"

40
zic.c
View File

@@ -723,6 +723,34 @@ warning(_("hard link failed, symbolic link used"));
static const zic_t min_time = (zic_t) -1 << (TIME_T_BITS_IN_FILE - 1);
static const zic_t max_time = -1 - ((zic_t) -1 << (TIME_T_BITS_IN_FILE - 1));
/* Estimated time of the Big Bang, in seconds since the POSIX epoch.
zic does not output time stamps before this, partly because they
are physically suspect, and partly because GNOME mishandles them; see
GNOME bug 730332 <https://bugzilla.gnome.org/show_bug.cgi?id=730332>.
The following estimate for the Big Bang time is taken from:
Ade PAR, Aghanim N, Armitage-Caplan C et al. Planck 2013 results.
I. Overview of products and scientific results.
arXiv:1303.5062 2013-03-20 20:10:01 UTC
<http://arxiv.org/pdf/1303.5062v1> [PDF]
Page 36, Table 9, row Age/Gyr, column Planck+WP+highL+BAO best fit,
gives the value 13.7965. Multiplying this by 1000000000 and then
by 31557600 (the number of seconds in an astronomical year), yields
435384428400000000. This estimate intentionally ignores the
difference between the POSIX epoch and the paper's publication
date, as being beneath the paper's precision.
This estimate is approximate, and may change in future versions.
Please do not rely on its exact value. */
#ifndef BIG_BANG
#define BIG_BANG (-435384428400000000LL)
#endif
static const zic_t big_bang_time = BIG_BANG;
static int
itsdir(const char *const name)
{
@@ -1478,7 +1506,7 @@ writezone(const char *const name, const char *const string, char version)
toi = 0;
fromi = 0;
while (fromi < timecnt && attypes[fromi].at < min_time)
while (fromi < timecnt && attypes[fromi].at < big_bang_time)
++fromi;
for ( ; fromi < timecnt; ++fromi) {
if (toi > 1 && ((attypes[fromi].at +
@@ -2167,9 +2195,9 @@ outzone(const struct zone * const zpfirst, const int zonecount)
*/
stdoff = 0;
zp = &zpfirst[i];
usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
usestart = i > 0 && (zp - 1)->z_untiltime > big_bang_time;
useuntil = i < (zonecount - 1);
if (useuntil && zp->z_untiltime <= min_time)
if (useuntil && zp->z_untiltime <= big_bang_time)
continue;
gmtoff = zp->z_gmtoff;
eat(zp->z_filename, zp->z_linenum);
@@ -2185,7 +2213,7 @@ outzone(const struct zone * const zpfirst, const int zonecount)
if (usestart) {
addtt(starttime, type);
usestart = FALSE;
} else addtt(min_time, type);
} else addtt(big_bang_time, type);
} else for (year = min_year; year <= max_year; ++year) {
if (useuntil && year > zp->z_untilrule.r_hiyear)
break;
@@ -2362,8 +2390,8 @@ error(_("can't determine time zone abbreviation to use just after until time"));
static void
addtt(const zic_t starttime, int type)
{
if (starttime <= min_time ||
(timecnt == 1 && attypes[0].at < min_time)) {
if (starttime <= big_bang_time ||
(timecnt == 1 && attypes[0].at < big_bang_time)) {
gmtoffs[0] = gmtoffs[type];
isdsts[0] = isdsts[type];
ttisstds[0] = ttisstds[type];