Weird .astimezone behavior

余生颓废 提交于 2019-12-04 03:03:36

问题


I am doing some timezone conversions, and I get really weird results. Basically converting between timezones that differ only by whole hours, I still get non-whole results. For example:

from datetime import datetime
from pytz import timezone

datetime(2013, 12, 27, 20, 0, 0, tzinfo=timezone('Europe/Bucharest'))\
    .astimezone(timezone('Europe/Berlin')).replace(tzinfo=None)

gives me

datetime.datetime(2013, 12, 27, 19, 16)

(time difference between Bucharest and Berlin is 1 hour, so I should get 19:00 - instead I get 19:16)

I'm probably missing something really obvious, but I can't figure it out. What am I doing wrong?


回答1:


As specified by the pytz documentation:

Unfortunately using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones.

Indeed, this is not the expected result, the timezone is wrong:

>>> datetime(2013, 12, 27, 20, 0, 0, tzinfo=timezone('Europe/Bucharest'))
datetime.datetime(2013, 12, 27, 20, 0,
    tzinfo=<DstTzInfo 'Europe/Bucharest' BMT+1:44:00 STD>)

This is explained the pytz constructor given the timezone('Europe/Bucharest') timezone does not check when the timezone offset should be considered, and these things tend to change over time. pytz just uses the earlier known definition, which will often be wrong:

>>> timezone('Europe/Bucharest')
<DstTzInfo 'Europe/Bucharest' BMT+1:44:00 STD>

It looks like this timezone was used until 1931.

There is no such issue when working with UTC times and converting those using astimezone (for display purposes only as recommended):

>>> datetime(2013, 12, 27, 20, 0, 0, tzinfo=pytz.utc)\
    .astimezone(timezone('Europe/Bucharest')) 
datetime.datetime(2013, 12, 27, 22, 0,
    tzinfo=<DstTzInfo 'Europe/Bucharest' EET+2:00:00 STD>)

Then you get the expected result:

>>> datetime(2013, 12, 27, 20, 0, 0, tzinfo=pytz.utc)\
    .astimezone(timezone('Europe/Bucharest'))\
    .astimezone(timezone('Europe/Berlin'))\
    .replace(tzinfo=None)
datetime.datetime(2013, 12, 27, 21, 0)



回答2:


I came across this same issue today, and eventually solved it using the answer @jfs put in the comment of the currently accepted answer. To help anyone else finding this in the future, here is a quick example of what does and doesn't work:

from datetime import datetime
import pytz

naive = datetime.now()
la_tz = pytz.timezone("America/Los_Angeles")

# this doesn't work
with_tz = naive.replace(tzinfo=la_tz)
converted_to_utc = with_tz.astimezone(pytz.utc)
print(converted_to_utc)

# this does work
with_tz = la_tz.localize(naive)
converted_to_utc = with_tz.astimezone(pytz.utc)
print(converted_to_utc)


来源:https://stackoverflow.com/questions/20804837/weird-astimezone-behavior

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!