summaryrefslogtreecommitdiff
path: root/src/timezone/localtime.c
diff options
context:
space:
mode:
authorTom Lane2020-06-17 22:29:29 +0000
committerTom Lane2020-06-17 22:29:42 +0000
commitd8b15eeb8a1acbe01b502ddd3390d7f1824c7a25 (patch)
treea88f950a6719f4600cd0691af5c860c1e2ce3512 /src/timezone/localtime.c
parent6924c37f772cd7701d3e1267a1fb3221ca159ba4 (diff)
Sync our copy of the timezone library with IANA release tzcode2020a.
This absorbs a leap-second-related bug fix in localtime.c, and teaches zic to handle an expiration marker in the leapseconds file. Neither are of any interest to us (for the foreseeable future anyway), but we need to stay more or less in sync with upstream. Also adjust some over-eager changes in the README from commit 957338418. I have no intention of making changes that require C99 in this code, until such time as all the live back branches require C99. Otherwise back-patching will get too exciting. For the same reason, absorb assorted whitespace and other cosmetic changes from HEAD into the back branches; mostly this reflects use of improved versions of pgindent. All in all then, quite a boring update. But I figured I'd get it done while I was looking at this code.
Diffstat (limited to 'src/timezone/localtime.c')
-rw-r--r--src/timezone/localtime.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/timezone/localtime.c b/src/timezone/localtime.c
index 787f0b69d63..0f65f3c648e 100644
--- a/src/timezone/localtime.c
+++ b/src/timezone/localtime.c
@@ -92,6 +92,7 @@ struct rule
static struct pg_tm *gmtsub(pg_time_t const *, int32, struct pg_tm *);
static bool increment_overflow(int *, int);
static bool increment_overflow_time(pg_time_t *, int32);
+static int64 leapcorr(struct state const *, pg_time_t);
static struct pg_tm *timesub(pg_time_t const *, int32, struct state const *,
struct pg_tm *);
static bool typesequiv(struct state const *, int, int);
@@ -477,12 +478,14 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
for (i = 0; i < ts->timecnt; i++)
if (sp->timecnt == 0
- || sp->ats[sp->timecnt - 1] < ts->ats[i])
+ || (sp->ats[sp->timecnt - 1]
+ < ts->ats[i] + leapcorr(sp, ts->ats[i])))
break;
while (i < ts->timecnt
&& sp->timecnt < TZ_MAX_TIMES)
{
- sp->ats[sp->timecnt] = ts->ats[i];
+ sp->ats[sp->timecnt]
+ = ts->ats[i] + leapcorr(sp, ts->ats[i]);
sp->types[sp->timecnt] = (sp->typecnt
+ ts->types[i]);
sp->timecnt++;
@@ -1601,6 +1604,22 @@ increment_overflow_time(pg_time_t *tp, int32 j)
return false;
}
+static int64
+leapcorr(struct state const *sp, pg_time_t t)
+{
+ struct lsinfo const *lp;
+ int i;
+
+ i = sp->leapcnt;
+ while (--i >= 0)
+ {
+ lp = &sp->lsis[i];
+ if (t >= lp->ls_trans)
+ return lp->ls_corr;
+ }
+ return 0;
+}
+
/*
* Find the next DST transition time in the given zone after the given time
*