0

I need to compare pytz.timezones for equality, and the behavior I'm observing is quite unintuitive. I've read a lot about Python time zones, pytz, zoneinfo, LMT, etc., both on SO and generally on the web. The behavior I'm concerned about does not seem to be obviously related to the typical concerns people have with pytz and solved similarly. The only workaround I've found is comparing the pytz.timezone.zone strings, which is clunky. The two examples below show the pytz.timezone comparison behavior. Used: Python==3.9, pytz==2022.2.1, pandas==1.5.3. The behavior of zoneinfo.ZoneInfo objects is, in contrast, sane and intuitive.

Example 1, LMT:

>>> tz = pytz.timezone("America/Chicago")
>>> tz
<DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD>
>>> tz.localize(datetime.now()).tzinfo == tz
False
>>> pd.DataFrame({'t': [tz.localize(datetime.now())]}).t.dt.tz == tz
True
>>> pd.DataFrame({'t': [tz.localize(datetime.now())]}).t.dt.tz_convert(tz).dt.tz == tz
True

Example 2, CST:

>>> tz = pytz.timezone("America/Chicago").localize(datetime.now()).tzinfo
>>> tz
<DstTzInfo 'America/Chicago' CST-1 day, 18:00:00 STD>
>>> tz.localize(datetime.now()).tzinfo == tz
True
>>> pd.DataFrame({'t': [tz.localize(datetime.now())]}).t.dt.tz == tz
False
>>> pd.DataFrame({'t': [tz.localize(datetime.now())]}).t.dt.tz_convert(tz).dt.tz == tz
False

I expect no False comparisons above, which is exactly what I get if I use zoneinfo instead.

  • I'd be curious what you have in mind with that comparison. I mean, ad hoc I don't see much worth in comparing *timezone objects*. I'd rather compare date/times that have been localized with timezone objects from different sources, to see if those sources implement the underlying time zone rules correctly. – FObersteiner Feb 10 '23 at 20:41
  • 2
    When you call `localize` you change the internal state of the `pytz` object and it's no longer equal. The `zoneinfo` objects are implemented differently and don't need internal state. – Mark Ransom Feb 10 '23 at 21:15
  • @FObersteiner Comparing timezone objects is useful for unit testing any code that deals with time zones, to mention one obvious use case. @MarkRansom I don't see any mention of internal state and its mutation in the documentation of `pytz.timezone.localize`, which simply states `Convert naive time to local time`. @СергейКох To quote myself, "I expect no False comparisons above, which is exactly what I get if I use zoneinfo instead." I think that's the reasonable ask. To have timezone comparisons behave consistently in the two examples I gave would be also make sense. – Georgi Peev Feb 10 '23 at 22:44
  • Maybe Paul Ganssles [blog post on pytz](https://blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html) helps to clarify the background. My take-away here would be to use zoneinfo if I can. Related: [pytz deprecation shim](https://pypi.org/project/pytz-deprecation-shim). Anyways, what do you want to test here, if the tz is set correctly? – FObersteiner Feb 11 '23 at 08:26
  • @FObersteiner I was working on unit tests where I need to verify that the timezone-aware datetimes are written and read back correctly from some persistence layer. I do test the datetimes themselves, but I wanted to also make sure that the time zones also match, because datetimes of different zones are considered equal if they correspond to the same time (`dt.astimezone(tz) == dt` evaluates to `True` despite the LHS/RHS datetimes having different timezones). – Georgi Peev Feb 13 '23 at 01:31
  • related: [Check whether timezone is dateutil.tz instance](https://stackoverflow.com/q/75314041/10197418) – FObersteiner Feb 14 '23 at 08:11

0 Answers0