Skip to content

Commit 812a84d

Browse files
committed
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 9573384. 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.
1 parent b91cfaa commit 812a84d

File tree

5 files changed

+143
-77
lines changed

5 files changed

+143
-77
lines changed

src/timezone/README

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ match properly on the old version.
5555
Time Zone code
5656
==============
5757

58-
The code in this directory is currently synced with tzcode release 2019b.
58+
The code in this directory is currently synced with tzcode release 2020a.
5959
There are many cosmetic (and not so cosmetic) differences from the
6060
original tzcode library, but diffs in the upstream version should usually
6161
be propagated to our version. Here are some notes about that.

src/timezone/localtime.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* in which Daylight Saving Time is never observed.
3737
* 4. They might reference tzname[0] after setting to a time zone
3838
* in which Standard Time is never observed.
39-
* 5. They might reference tm.TM_ZONE after calling offtime.
39+
* 5. They might reference tm.tm_zone after calling offtime.
4040
* What's best to do in the above cases is open to debate;
4141
* for now, we just set things up so that in any of the five cases
4242
* WILDABBR is used. Another possibility: initialize tzname[0] to the
@@ -92,6 +92,7 @@ struct rule
9292
static struct pg_tm *gmtsub(pg_time_t const *, int32, struct pg_tm *);
9393
static bool increment_overflow(int *, int);
9494
static bool increment_overflow_time(pg_time_t *, int32);
95+
static int64 leapcorr(struct state const *, pg_time_t);
9596
static struct pg_tm *timesub(pg_time_t const *, int32, struct state const *,
9697
struct pg_tm *);
9798
static bool typesequiv(struct state const *, int, int);
@@ -138,7 +139,7 @@ detzcode(const char *const codep)
138139
* Do two's-complement negation even on non-two's-complement machines.
139140
* If the result would be minval - 1, return minval.
140141
*/
141-
result -= !TWOS_COMPLEMENT(int32) &&result != 0;
142+
result -= !TWOS_COMPLEMENT(int32) && result != 0;
142143
result += minval;
143144
}
144145
return result;
@@ -152,7 +153,7 @@ detzcode64(const char *const codep)
152153
int64 one = 1;
153154
int64 halfmaxval = one << (64 - 2);
154155
int64 maxval = halfmaxval - 1 + halfmaxval;
155-
int64 minval = -TWOS_COMPLEMENT(int64) -maxval;
156+
int64 minval = -TWOS_COMPLEMENT(int64) - maxval;
156157

157158
result = codep[0] & 0x7f;
158159
for (i = 1; i < 8; ++i)
@@ -164,7 +165,7 @@ detzcode64(const char *const codep)
164165
* Do two's-complement negation even on non-two's-complement machines.
165166
* If the result would be minval - 1, return minval.
166167
*/
167-
result -= !TWOS_COMPLEMENT(int64) &&result != 0;
168+
result -= !TWOS_COMPLEMENT(int64) && result != 0;
168169
result += minval;
169170
}
170171
return result;
@@ -173,7 +174,7 @@ detzcode64(const char *const codep)
173174
static bool
174175
differ_by_repeat(const pg_time_t t1, const pg_time_t t0)
175176
{
176-
if (TYPE_BIT(pg_time_t) -TYPE_SIGNED(pg_time_t) <SECSPERREPEAT_BITS)
177+
if (TYPE_BIT(pg_time_t) - TYPE_SIGNED(pg_time_t) < SECSPERREPEAT_BITS)
177178
return 0;
178179
return t1 - t0 == SECSPERREPEAT;
179180
}
@@ -477,12 +478,14 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
477478

478479
for (i = 0; i < ts->timecnt; i++)
479480
if (sp->timecnt == 0
480-
|| sp->ats[sp->timecnt - 1] < ts->ats[i])
481+
|| (sp->ats[sp->timecnt - 1]
482+
< ts->ats[i] + leapcorr(sp, ts->ats[i])))
481483
break;
482484
while (i < ts->timecnt
483485
&& sp->timecnt < TZ_MAX_TIMES)
484486
{
485-
sp->ats[sp->timecnt] = ts->ats[i];
487+
sp->ats[sp->timecnt]
488+
= ts->ats[i] + leapcorr(sp, ts->ats[i]);
486489
sp->types[sp->timecnt] = (sp->typecnt
487490
+ ts->types[i]);
488491
sp->timecnt++;
@@ -1480,7 +1483,7 @@ timesub(const pg_time_t *timep, int32 offset,
14801483
int leapdays;
14811484

14821485
tdelta = tdays / DAYSPERLYEAR;
1483-
if (!((!TYPE_SIGNED(pg_time_t) ||INT_MIN <= tdelta)
1486+
if (!((!TYPE_SIGNED(pg_time_t) || INT_MIN <= tdelta)
14841487
&& tdelta <= INT_MAX))
14851488
goto out_of_range;
14861489
idelta = tdelta;
@@ -1601,6 +1604,22 @@ increment_overflow_time(pg_time_t *tp, int32 j)
16011604
return false;
16021605
}
16031606

1607+
static int64
1608+
leapcorr(struct state const *sp, pg_time_t t)
1609+
{
1610+
struct lsinfo const *lp;
1611+
int i;
1612+
1613+
i = sp->leapcnt;
1614+
while (--i >= 0)
1615+
{
1616+
lp = &sp->lsis[i];
1617+
if (t >= lp->ls_trans)
1618+
return lp->ls_corr;
1619+
}
1620+
return 0;
1621+
}
1622+
16041623
/*
16051624
* Find the next DST transition time in the given zone after the given time
16061625
*

src/timezone/pgtz.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ pg_tzset_offset(long gmtoffset)
357357
* is to ensure that log_timezone has a valid value before any logging GUC
358358
* variables could become set to values that require elog.c to provide
359359
* timestamps (e.g., log_line_prefix). We may as well initialize
360-
* session_timestamp to something valid, too.
360+
* session_timezone to something valid, too.
361361
*/
362362
void
363363
pg_timezone_initialize(void)

src/timezone/strftime.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ static char *_fmt(const char *, const struct pg_tm *, char *, const char *,
118118
static char *_yconv(int, int, bool, bool, char *, char const *);
119119

120120

121+
/*
122+
* Convert timestamp t to string s, a caller-allocated buffer of size maxsize,
123+
* using the given format pattern.
124+
*
125+
* See also timestamptz_to_str.
126+
*/
121127
size_t
122128
pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
123129
{
@@ -499,7 +505,7 @@ _fmt(const char *format, const struct pg_tm *t, char *pt,
499505
static char *
500506
_conv(int n, const char *format, char *pt, const char *ptlim)
501507
{
502-
char buf[INT_STRLEN_MAXIMUM(int) +1];
508+
char buf[INT_STRLEN_MAXIMUM(int) + 1];
503509

504510
sprintf(buf, format, n);
505511
return _add(buf, pt, ptlim);

0 commit comments

Comments
 (0)