>>> import pytz
>>> pytz.timezone('Asia/Hong_Kong')
<DstTzInfo 'Asia/Hong_Kong' LMT+7:37:00 STD>
A seven hour and 37 minute offset? This is a little strange, does anyone experience the same issue?
In fact I’m getting different behavior between
import pytz
from datetime import datetime
hk = pytz.timezone('Asia/Hong_Kong')
dt1 = datetime(2012,1,1,tzinfo=hk)
dt2 = hk.localize(datetime(2012,1,1))
if dt1 > dt2:
print "Why?"
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Time zones and offsets change over the years. The default zone name and offset delivered when pytz creates a timezone object are the earliest ones available for that zone, and sometimes they can seem kind of strange. When you use localize to attach the zone to a date, the proper zone name and offset are substituted. Simply using the datetime constructor to attach the zone to the date doesn’t allow it to adjust properly.
Method 2
While I’m sure historic changes in timezones are a factor, passing pytz timezone object to the DateTime constructor results in odd behavior even for timezones that have experienced no changes since their inception.
import datetime
import pytz
dt = datetime.datetime(2020, 7, 15, 0, 0, tzinfo= pytz.timezone('US/Eastern'))
produces
2020-07-15 00:00:00-04:56
Creating the datetime object then localizing it produced expected results
import datetime
import pytz
dt = datetime.datetime(2020, 7, 15, 0, 0)
dt_local = timezone('US/Eastern').localize(dt)
produces
2020-07-15 00:00:00-04:00
Method 3
Coming here nearly 10 years later, I think it’s worth a note that we can now exclusively utilize the Python 3.9+ standard library to handle time zones, without a “localize trap”.
Use the zoneinfo module to set and replace the tzinfo however you like, ex:
from datetime import datetime
from zoneinfo import ZoneInfo
hk = ZoneInfo('Asia/Hong_Kong')
print(repr(hk))
# zoneinfo.ZoneInfo(key='Asia/Hong_Kong')
dt1 = datetime(2012,1,1,tzinfo=hk)
print(dt1)
# 2012-01-01 00:00:00+08:00
- there is a deprecation shim for
pytz
Alternatives, if you’re not able to use zoneinfo:
- for Python < 3.9, there’s backports.zoneinfo
- you could also use dateutil, which follows the same semantics as
zoneinfo
Note for pandas users:
pandas(v1.4.1) is still usingpytzinternally, and seems to have some trouble with ZoneInfo timezone objects
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0