From 6c30e400bd8ac791e70c19d0c49d17fcbcc25ee2 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Fri, 17 Apr 2020 13:26:37 -0400 Subject: [PATCH 1/2] Add Africa/Abidjan This has a single transition, from LMT to GMT, in 1912. --- tests/data/zoneinfo_data.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/data/zoneinfo_data.json b/tests/data/zoneinfo_data.json index 080a54b2..00d31930 100644 --- a/tests/data/zoneinfo_data.json +++ b/tests/data/zoneinfo_data.json @@ -1,4 +1,9 @@ { + "Africa/Abidjan": [ + "{Wp48S^xk9=GL@E0stWa761SMbT8$j-~f{VGF<>F7KxBg5R*{Ksocg8-YYVul=v7vZzaHN", + "uC=da5UI2rH18c!OnjV{y4u(+A!!VBKmY&$ORw>7UO^(500B;v0RR91bXh%WvBYQl0ssI2", + "00dcD" + ], "Africa/Casablanca": [ "{Wp48S^xk9=GL@E0stWa761SMbT8$j;0b&K$Xx&`7KxBg5R*{N&yjMUR~;C-fDaSOU;q-~", "FqW+4{YBjbcw}`a!dW>b)R2-0a+uwf`P3{_Y@HuCz}S$J$ZJ>R_V<~|Fk>sgX4=%0vUrh-", From bfc87e6a49ac12126c5e9d257d068c7110ed3bca Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Fri, 17 Apr 2020 13:50:02 -0400 Subject: [PATCH 2/2] Fix fold handling for one-transition zones Prior to this change, when a zone has a single transition (particularly to a zone with no DST), the fold handling logic in the C extension was broken, because the logic for detecting how to handle the first offset was incorrectly based on the number of transitions rather than the number of ttinfos. This bug was discovered by running the property tests over and over again hundreds of times; the minimal reproducing case has also been added to the unit tests. --- lib/zoneinfo_module.c | 11 +++++++---- tests/test_zoneinfo.py | 9 +++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/zoneinfo_module.c b/lib/zoneinfo_module.c index 4724a267..72bd1e5f 100644 --- a/lib/zoneinfo_module.c +++ b/lib/zoneinfo_module.c @@ -95,7 +95,8 @@ utcoff_to_dstoff(size_t *trans_idx, long *utcoffs, long *dstoffs, size_t num_ttinfos); static int ts_to_local(size_t *trans_idx, int64_t *trans_utc, long *utcoff, - int64_t *trans_local[2], size_t num_transitions); + int64_t *trans_local[2], size_t num_ttinfos, + size_t num_transitions); static int parse_tz_str(PyObject *tz_str_obj, _tzrule *out); @@ -905,7 +906,8 @@ load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj) self->num_ttinfos); if (ts_to_local(trans_idx, self->trans_list_utc, utcoff, - self->trans_list_wall, self->num_transitions)) { + self->trans_list_wall, self->num_ttinfos, + self->num_transitions)) { goto error; } @@ -1930,7 +1932,8 @@ utcoff_to_dstoff(size_t *trans_idx, long *utcoffs, long *dstoffs, */ static int ts_to_local(size_t *trans_idx, int64_t *trans_utc, long *utcoff, - int64_t *trans_local[2], size_t num_transitions) + int64_t *trans_local[2], size_t num_ttinfos, + size_t num_transitions) { if (num_transitions == 0) { return 0; @@ -1947,7 +1950,7 @@ ts_to_local(size_t *trans_idx, int64_t *trans_utc, long *utcoff, } int64_t offset_0, offset_1, buff; - if (num_transitions > 1) { + if (num_ttinfos > 1) { offset_0 = utcoff[0]; offset_1 = utcoff[trans_idx[0]]; diff --git a/tests/test_zoneinfo.py b/tests/test_zoneinfo.py index 1c1244ae..47f773e9 100644 --- a/tests/test_zoneinfo.py +++ b/tests/test_zoneinfo.py @@ -1610,6 +1610,14 @@ def _get_zonedump(cls): @classmethod def _populate_zonedump_data(cls): + def _Africa_Abidjan(): + LMT = ZoneOffset("LMT", timedelta(seconds=-968)) + GMT = ZoneOffset("GMT", ZERO) + + return [ + ZoneTransition(datetime(1912, 1, 1), LMT, GMT), + ] + def _Africa_Casablanca(): P00_s = ZoneOffset("+00", ZERO, ZERO) P01_d = ZoneOffset("+01", ONE_H, ONE_H) @@ -1760,6 +1768,7 @@ def _Pacific_Kiritimati(): ] cls._ZONEDUMP_DATA = { + "Africa/Abidjan": _Africa_Abidjan(), "Africa/Casablanca": _Africa_Casablanca(), "America/Los_Angeles": _America_Los_Angeles(), "America/Santiago": _America_Santiago(),