Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for version 2+ zoneinfo files with fallback TZ variable #590

Open
pganssle opened this issue Dec 13, 2017 · 3 comments
Open

Support for version 2+ zoneinfo files with fallback TZ variable #590

pganssle opened this issue Dec 13, 2017 · 3 comments

Comments

@pganssle
Copy link
Member

When trying to use hypothesis to test whether there's a 1->1 mapping of pytz zones to dateutil zones, I wrote the following test:

from hypothesis import given, assume
from hypothesis import strategies as st
from hypothesis.extra import pytz as hepytz

from dateutil import tz
from datetime import datetime

@given(dt=st.datetimes(), tzi=hepytz.timezones())
def test_dateutil_compat(dt, tzi):
    # Test passes if you remove this assertion
    # assume(dt < datetime(2038, 1, 1))
    tzi_du = tz.gettz(str(tzi))
    dt_pytz = tzi.localize(dt)
    dt_du = dt.replace(tzinfo=tzi_du)

    assert dt_pytz == dt_du

This property is falsified by various examples after 2038-01-01:

E       AssertionError: assert datetime.datetime(2038, 1, 1, 0, 0, tzinfo=<DstTzInfo 'America/Campo_Grande' -03-1 day, 21:00:00 DST>) == datetime.datetime(2038, 1, 1, 0, 0, tzinfo=tzfile('/usr/share/zoneinfo/America/Campo_Grande'))

E       AssertionError: assert datetime.datetime(2038, 1, 1, 0, 0, tzinfo=<DstTzInfo 'Antarctica/South_Pole' NZDT+13:00:00 DST>) == datetime.datetime(2038, 1, 1, 0, 0, tzinfo=tzfile('/usr/share/zoneinfo/Antarctica/South_Pole'))

This is probably partially related to #462, since 2038 is the last year that there transitions in the 32-bit version of the files, but I am guessing that this means that we're doing the "default" rule differently from how pytz does it. I'm not sure who is right, but I wouldn't be surprised if it were pytz. I think we should fix this before #462, because since pytz does not support the 64-bit format, once we add support it may break the symmetry without solving the real problem.

@pganssle
Copy link
Member Author

I think the reason here is that after the last transition, dateutil falls back to STD time, pytz evidently falls back to whatever the last transition was. In the southern hemisphere, the last 32-bit dates are zones are on the DST side, which creates the discrepancy.

I'm not sure there's a "right" answer here, but my inclination is that falling back to standard feels right.

@pganssle
Copy link
Member Author

pganssle commented Dec 13, 2017

I'm actually not really sure why there's a _ttinfo_std at all in this approach. It doesn't seem like it should be a meaningful concept - it just represents the first non-DST offset in the file. I don't see why this should get a special place of privilege. If we eliminate it, we'll either need to add _ttinfo_after (which will hold the last non-DST zone after the last transition) or switch to pytz's behavior of "holding" after the last transition.

I think I've probably convinced myself that it's easiest to just take pytz's approach here, since both choices are defensible and pytz's approach requires no special handling.

@pganssle
Copy link
Member Author

Actually, both pytz and dateutil are doing it wrong. When we fix #462 to read the 64-bit version of the files, in version 2+, there is a POSIX TZ-variable style null-terminated string at the end of the file that says what to do after the last transition - we can add support then.

@pganssle pganssle changed the title Difference between pytz and dateutil after 2038-01-01 Support for version 2+ zoneinfo files with fallback TZ variable Dec 13, 2017
@pganssle pganssle added this to Open in PyData NYC Sprint Apr 11, 2018
@pganssle pganssle removed this from Open in PyData NYC Sprint Apr 11, 2018
@pganssle pganssle removed this from Open in PyLondinium 2018 Sprint Jun 8, 2018
pganssle added a commit to pganssle/dateutil that referenced this issue Aug 28, 2020
At the moment, we do not support Version 2 files (see dateutilGH-590), and many
zones will be inaccurate *today* when dateutil.tz is used with a slim
binary. For the moment, we'll force fat binaries. In the long term,
we'll migrate to something like zoneinfo.
pganssle added a commit to pganssle/dateutil that referenced this issue Aug 28, 2020
At the moment, we do not support Version 2 files (see dateutilGH-590), and many
zones will be inaccurate *today* when dateutil.tz is used with a slim
binary. For the moment, we'll force fat binaries. In the long term,
we'll migrate to something like zoneinfo.
pganssle added a commit to pganssle/dateutil that referenced this issue Aug 28, 2020
At the moment, we do not support Version 2 files (see dateutilGH-590), and many
zones will be inaccurate *today* when dateutil.tz is used with a slim
binary. For the moment, we'll force fat binaries. In the long term,
we'll migrate to something like zoneinfo.
pganssle added a commit to pganssle/dateutil that referenced this issue Aug 28, 2020
At the moment, we do not support Version 2 files (see dateutilGH-590), and many
zones will be inaccurate *today* when dateutil.tz is used with a slim
binary. For the moment, we'll force fat binaries. In the long term,
we'll migrate to something like zoneinfo.
pganssle added a commit to pganssle/dateutil that referenced this issue Aug 28, 2020
At the moment, we do not support Version 2 files (see dateutilGH-590), and many
zones will be inaccurate *today* when dateutil.tz is used with a slim
binary. For the moment, we'll force fat binaries. In the long term,
we'll migrate to something like zoneinfo.
pganssle added a commit to pganssle/dateutil that referenced this issue Aug 28, 2020
At the moment, we do not support Version 2 files (see dateutilGH-590), and many
zones will be inaccurate *today* when dateutil.tz is used with a slim
binary. For the moment, we'll force fat binaries. In the long term,
we'll migrate to something like zoneinfo.
pganssle added a commit to pganssle/dateutil that referenced this issue Aug 28, 2020
At the moment, we do not support Version 2 files (see dateutilGH-590), and many
zones will be inaccurate *today* when dateutil.tz is used with a slim
binary. For the moment, we'll force fat binaries. In the long term,
we'll migrate to something like zoneinfo.
nickgeorge pushed a commit to google/fhir that referenced this issue Oct 26, 2020
Previously, `_primitive_time_utils.py` leveraged `dateutil` for datetime
timezone arithmetic. However, `dateutil` is unable to properly account for dst
offsets when performing datetime arithemtic for dates in the distant future.
This is a known `dateutil` bug and more info can be found at:
* dateutil/dateutil#462
* dateutil/dateutil#590

This is addressed with PEP615 (https://www.python.org/dev/peps/pep-0615/) for
interpreters >=3.9. `backports.zoneinfo` provides backwards compatibility API
for interpreters >=3.6, <3.9 which we leverage here.

PiperOrigin-RevId: 336909567
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant