13

Is there anyone who can help me understand what's going on here?

import pytz
from datetime import datetime
tz = pytz.timezone('Europe/Berlin')
print repr(tz)
# <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>
dt = datetime(2011, 1, 3, 18, 40)
result = tz.localize(dt)
print repr(result.tzinfo)
# <DstTzInfo 'Europe/Berlin' CET+1:00:00 STD>
assert result.tzinfo == tz, "Why aren't these the same timezone?"

My understanding was that the localize() method on a pytz timezone object would take a naive datetime object, and add a tzinfo property that matches the timezone object performing the localization. That does not appear to be happening in this case.

Clearly, there's something I'm misunderstanding about timezones, or about the way that pytz handles timezones. Can anyone explain?

bjmc
  • 2,970
  • 2
  • 32
  • 46

1 Answers1

14

They are the same time zone - "Europe/Berlin".

When you are printing them, the output includes the abbreviation and offset that applies at that particular point in time.

If you examine the tz data sources, you'll see:

# Zone  NAME            GMTOFF   RULES       FORMAT   [UNTIL]
Zone    Europe/Berlin   0:53:28  -           LMT      1893 Apr
                        1:00     C-Eur       CE%sT    1945 May 24 2:00
                        1:00     SovietZone  CE%sT    1946
                        1:00     Germany     CE%sT    1980
                        1:00     EU          CE%sT

So it would appear that when the time zone has not localized a datetime, then it just uses the first entry.

It would also appear that pytz doesn't retain the extra 28 seconds from the original local mean time deviation - but that doesn't matter unless you are working with dates in Berlin before April 1893.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Thank you for your comment. Good catch on the CET/CEST. That was a bad copy-paste on my part (now edited). I had experimented with both a daylight savings date and a non-daylight savings date. I tried running this under Python 3.4 with the newest pytz, and got the same outcome. Please see: https://gist.github.com/bjmc/59d8650ae3d2aebb7584 Your information about the tz data source is appreciated. Does this mean that the `tzinfo` attribute of a [modern] localized date would never compare equal with the abstract timezone object from pytz? – bjmc Jun 23 '14 at 22:02
  • 2
    In general, I wouldn't consider a `tzinfo` to ever be comparable to another `tzinfo` without a specific date and time in mind. However, if you know that both objects are from pytz (or from [tzlocal](https://pypi.python.org/pypi/tzlocal)), you can compare their `.zone` properties, which just contain the string of the zone identifier (`"Europe/Berlin"`). – Matt Johnson-Pint Jun 23 '14 at 22:15
  • 1
    Not sure this is an answer. It's just repeating that it's a problem. The problem happens when you try to replace the tzinfo of a datetime object too. – Peter Bengtsson Dec 04 '15 at 17:54
  • 2
    @PeterBengtsson - Then don't use replace, use `localize`. The question was asking for understanding of *why* it happens, so that's how this answer was phrased. – Matt Johnson-Pint Dec 04 '15 at 18:05
  • 1
    @MattJohnson I get it now. The trick IS to always use `localize()`. Even if that means you have to first convert it to a timezone *naive* datetime so you can localize it back. – Peter Bengtsson Dec 04 '15 at 18:46