简体   繁体   English

奇怪的.astimezone行为

[英]Weird .astimezone behavior

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) (布加勒斯特和柏林之间的时差是1小时,所以我应该得到19:00 - 而不是19:16)

I'm probably missing something really obvious, but I can't figure it out. 我可能错过了一些非常明显的东西,但我无法弄清楚。 What am I doing wrong? 我究竟做错了什么?

As specified by the pytz documentation : pytz文档指定:

Unfortunately using the tzinfo argument of the standard datetime constructors ''does not work'' with pytz for many timezones. 不幸的是,对于许多时区,使用标准日期时间构造函数的'tzinfo参数''与pytz不兼容。

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构造函数给定时timezone('Europe/Bucharest')时区不检查何时应该考虑时区偏移,并且这些事情往往会随着时间的推移而改变。 pytz just uses the earlier known definition, which will often be wrong: pytz只使用早期已知的定义,这通常是错误的:

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

It looks like this timezone was used until 1931 . 看起来这个时区一直使用到1931年

There is no such issue when working with UTC times and converting those using astimezone (for display purposes only as recommended): 使用UTC时间并使用astimezone转换时不存在此类问题(仅出于推荐目的显示):

>>> 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)

I came across this same issue today, and eventually solved it using the answer @jfs put in the comment of the currently accepted answer. 我今天遇到了同样的问题,并最终使用当前接受的答案的评论中的@jfs答案来解决它。 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM