[tz] [PROPOSED] zic option for including data from a certain year onward

Christopher Wong christopher.wong at axis.com
Tue Mar 5 07:33:35 UTC 2019


>From 4093e426a42421fd2d8579b07e8edb3fb116f561 Mon Sep 17 00:00:00 2001
From: Christopher Wong <christwo at axis.com>
Date: Tue, 5 Feb 2019 15:02:57 +0100
Subject: [PATCH] zic.c: Add -k option to keep specified year and onward

The -k option will take a year as input. It will strip away
historical transition data before the specified year. The
TZif files will be truncated.
---
 zic.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 69 insertions(+), 3 deletions(-)

diff --git a/zic.c b/zic.c
index 2ebc66a..9a3b1f5 100644
--- a/zic.c
+++ b/zic.c
@@ -178,6 +178,7 @@ static void mkdirs(char const *, bool);
 static void newabbr(const char * abbr);
 static zic_t oadd(zic_t t1, zic_t t2);
 static void outzone(const struct zone * zp, ptrdiff_t ntzones);
+static zic_t ytime(zic_t year);
 static zic_t rpytime(const struct rule * rp, zic_t wantedy);
 static void rulesub(struct rule * rp,
  const char * loyearp, const char * hiyearp,
@@ -610,6 +611,10 @@ static const char * leapsec;
 static const char * tzdefault;
 static const char * yitcommand;

+/* This is used to truncate tzfiles. Only year specified by keepyear and
+   onward will be kept. Don't expect year to be outside range 0-9999. */
+static zic_t keepyear;
+
 int
 main(int argc, char **argv)
 {
@@ -640,7 +645,8 @@ main(int argc, char **argv)
  } else if (strcmp(argv[k], "--help") == 0) {
  usage(stdout, EXIT_SUCCESS);
  }
- while ((c = getopt(argc, argv, "d:l:L:p:st:vy:")) != EOF && c != -1)
+ keepyear = ZIC_MIN;
+ while ((c = getopt(argc, argv, "d:k:l:L:p:st:vy:")) != EOF && c != -1)
  switch (c) {
  default:
  usage(stderr, EXIT_FAILURE);
@@ -654,6 +660,22 @@ _("%s: More than one -d option specified\n"),
  return EXIT_FAILURE;
  }
  break;
+ case 'k':
+ if (keepyear == ZIC_MIN) {
+ keepyear = atoi(optarg);
+ /* Don't expect year to be outside range 0-9999. */
+ if (keepyear < 0)
+ keepyear = 0;
+ if (keepyear > 9999)
+ keepyear = 9999;
+ }
+ else {
+ fprintf(stderr,
+_("%s: More than one -k option specified\n"),
+ progname);
+ return EXIT_FAILURE;
+ }
+ break;
  case 'l':
  if (lcltime == NULL)
  lcltime = optarg;
@@ -1749,7 +1771,7 @@ writezone(const char *const name, const char *const string, char version,
  register FILE * fp;
  register ptrdiff_t i, j;
  register int leapcnt32, leapi32;
- register ptrdiff_t timecnt32, timei32;
+ register ptrdiff_t timecnt32, timei32, timei;
  register int pass;
  static const struct tzhead tzh0;
  static struct tzhead tzh;
@@ -1865,6 +1887,37 @@ writezone(const char *const name, const char *const string, char version,
  --leapcnt32;
  ++leapi32;
  }
+
+ timei = 0;
+ if (keepyear != ZIC_MIN) {
+ /* Discard transitions that happened before the keepyear. */
+ int nbr_removes;
+
+ nbr_removes = 0;
+ for (i = timei32; i < timecnt; ++i)
+ if (ats[i] < ytime(keepyear))
+ ++nbr_removes;
+ timecnt32 -= nbr_removes;
+ timei32 += nbr_removes;
+
+ nbr_removes = 0;
+ for (i = 0; i < timecnt; ++i)
+ if (ats[i] < ytime(keepyear))
+ ++nbr_removes;
+
+ if (nbr_removes > 0) {
+ /* Override the last removed transition time with the first transition
+    time that is the start point of the truncation range. Set defaulttype
+    to this first transition time. */
+ --nbr_removes;
+ ats[nbr_removes] = ytime(keepyear);
+ defaulttype = types[nbr_removes];
+ }
+
+ timecnt -= nbr_removes;
+ timei += nbr_removes;
+ }
+
  /*
  ** Remove old file, if any, to snap links.
  */
@@ -1910,7 +1963,7 @@ writezone(const char *const name, const char *const string, char version,
  thisleapi = leapi32;
  thisleapcnt = leapcnt32;
  } else {
- thistimei = 0;
+ thistimei = timei;
  thistimecnt = timecnt;
  toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
  thisleapi = 0;
@@ -3107,6 +3160,19 @@ tadd(zic_t t1, zic_t t2)
 }

 /*
+** Given a year, compute the date (in seconds since January 1,
+** 1970, 00:00).
+*/
+
+static zic_t
+ytime(zic_t year)
+{
+ struct rule xr = { 0 };
+ xr.r_dayofmonth = 1;
+ return rpytime(&xr, year);
+}
+
+/*
 ** Given a rule, and a year, compute the date (in seconds since January 1,
 ** 1970, 00:00 LOCAL time) in that year that the rule refers to.
 */
--
2.11.0

?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mm.icann.org/pipermail/tz/attachments/20190305/cbfc5d48/attachment.html>


More information about the tz mailing list