[tz] [PROPOSED 3/3] zic -r now uses -00 for unspecified timestamps

Paul Eggert eggert at cs.ucla.edu
Fri Oct 15 09:01:25 UTC 2021


* NEWS, zic.8: Mention this.
* zic.c (unspecifiedtype): New static var.
(limitrange): Use unspecified time before -r low cutoff.
(writezone): Use it after -r high cutoff.
(outzone): Create unspecified time type if cutoffs are in use.
---
 NEWS  |  7 +++++++
 zic.8 |  6 +++++-
 zic.c | 24 ++++++++++++++----------
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/NEWS b/NEWS
index 6c658cb..d066849 100644
--- a/NEWS
+++ b/NEWS
@@ -4,12 +4,19 @@ Unreleased, experimental changes
 
   Briefly:
     Fiji suspends DST for the 2021/2022 season.
+    'zic -r' marks unspecified timestamps with "-00".
 
   Changes to future timestamps
 
     Fiji will suspend observance of DST for the 2021/2022 season.  Assume for
     now that it will return next year.  (Thanks to Jashneel Kumar and P Chan.)
 
+  Changes to code
+
+    'zic -r' now uses "-00" time zone abbreviations for intervals
+    with UT offsets that are unspecified due to -r truncation.
+    This implements a change in draft Internet RFC 8536bis.
+
 
 Release 2021c - 2021-10-01 14:21:49 -0700
 
diff --git a/zic.8 b/zic.8
index 89fc827..a0a9743 100644
--- a/zic.8
+++ b/zic.8
@@ -122,7 +122,7 @@ is
 any already-existing link is removed.
 .TP
 .BR "\*-r " "[\fB@\fP\fIlo\fP][\fB/@\fP\fIhi\fP]"
-Reduce the size of output files by limiting their applicability
+Limit the applicability of output files
 to timestamps in the range from
 .I lo
 (inclusive) to
@@ -134,6 +134,10 @@ and
 are possibly-signed decimal counts of seconds since the Epoch
 (1970-01-01 00:00:00 UTC).
 Omitted counts default to extreme values.
+The output files use UT offset 0 and abbreviation
+.q "\*-00"
+in place of the omitted timestamp data;
+this typically reduces the files' sizes.
 For example,
 .q "zic \*-r @0"
 omits data intended for negative timestamps (i.e., before the Epoch), and
diff --git a/zic.c b/zic.c
index 1f64058..b70a606 100644
--- a/zic.c
+++ b/zic.c
@@ -202,6 +202,7 @@ static const char *	progname;
 static ptrdiff_t	timecnt;
 static ptrdiff_t	timecnt_alloc;
 static int		typecnt;
+static int		unspecifiedtype;
 
 /*
 ** Line codes.
@@ -1972,6 +1973,10 @@ limitrange(struct timerange r, bool locut, zic_t lo, zic_t hi,
     r.base++;
   }
 
+  /* "-00" before any -r low cutoff.  */
+  if (min_time < lo_time)
+    r.defaulttype = unspecifiedtype;
+
   /* Omit as many initial leap seconds as possible, such that the
      first leap second in the truncated list is <= LO, and is a
      positive leap second if and only if it has a positive correction.
@@ -2155,7 +2160,7 @@ writezone(const char *const name, const char *const string, char version,
 		register ptrdiff_t thistimei, thistimecnt, thistimelim;
 		register int	thisleapi, thisleapcnt, thisleaplim;
 		struct tzhead tzh;
-		int currenttype, thisdefaulttype;
+		int thisdefaulttype;
 		bool hicut, pretrans, thisleapexpiry;
 		zic_t lo;
 		int old0;
@@ -2205,13 +2210,12 @@ writezone(const char *const name, const char *const string, char version,
 		  error(_("too many transition times"));
 
 		thistimelim = thistimei + thistimecnt;
-		if (thistimecnt && hi_time < max_time
-		    && ats[thistimelim - 1] == hi_time + 1)
-		  hicut = false;
 		memset(omittype, true, typecnt);
 		omittype[thisdefaulttype] = false;
 		for (i = thistimei - pretrans; i < thistimelim; i++)
 		  omittype[types[i]] = false;
+		if (hicut)
+		  omittype[unspecifiedtype] = false;
 
 		/* Reorder types to make THISDEFAULTTYPE type 0.
 		   Use TYPEMAP to swap OLD0 and THISDEFAULTTYPE so that
@@ -2347,13 +2351,10 @@ writezone(const char *const name, const char *const string, char version,
 		}
 		if (hicut)
 		  puttzcodepass(hi_time + 1, fp, pass);
-		currenttype = 0;
-		for (i = thistimei - pretrans; i < thistimelim; ++i) {
-		  currenttype = typemap[types[i]];
-		  putc(currenttype, fp);
-		}
+		for (i = thistimei - pretrans; i < thistimelim; ++i)
+		  putc(typemap[types[i]], fp);
 		if (hicut)
-		  putc(currenttype, fp);
+		  putc(typemap[unspecifiedtype], fp);
 
 		for (i = old0; i < typecnt; i++) {
 		  int h = (i == old0 ? thisdefaulttype
@@ -2868,6 +2869,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
 		max_year = 2038;
 	}
 
+	if (min_time < lo_time || hi_time < max_time)
+	  unspecifiedtype = addtype(0, "-00", false, false, false);
+
 	for (i = 0; i < zonecount; ++i) {
 		struct rule *prevrp = NULL;
 		zic_t prevktime;
-- 
2.30.2



More information about the tz mailing list