为什么使用来自pytz的tzinfo创建datetime会显示奇怪的时区偏移?

11

有人能解释一下为什么我在这两个地方得到的结果不同吗?

import datetime,pytz
var1 = datetime.datetime(2017,10,25,20,10,50,tzinfo=pytz.timezone("Europe/Athens")))
print(var1)

这段代码的输出是:2017-10-25 20:10:50+01:35

import datetime,pytz
var1 = datetime.datetime(2017,10,25,20,10,50)
var1 = pytz.timezone("Europe/Athens").localize(var1)
print(var1)

这段代码的输出结果是:2017-10-25 20:10:50+03:00

我的问题是为什么它们有不同的时区(1:35和3:00)。我知道第二个代码是正确的,因为我的协调世界时是3:00。但是你能告诉我为什么我在第一个代码中得到了1:35吗?


你在第二个例子中调用了 localize,而在第一个例子中没有。鉴于 pytz 的文档:该库仅支持两种构建本地化时间的方式。第一种是使用 localize()[...]第二种构建本地化时间的方法是通过使用标准的 astimezone() 转换现有的本地化时间,我会预期存在差异。 - Adonis
@KwnstantinosNikoloutsos 一旦您找到适合您的答案,请单击该答案旁边的勾选标记以接受它。这可以让其他遇到相同问题的人知道哪个解决方案适用于您。 - Adi219
1
@AdiC 好的,我只是在等更多人看到这个并写下来以解决我面临的问题。 - Kwnstantinos Nikoloutsos
可能是pytz中的奇怪时区问题的重复。 - FObersteiner
3个回答

5

没有问题,datetime只是愉快地报告了tzinfo在任何参考系中的偏移量。

默认情况下,pytz.timezone不会提供UTC偏移量,而是提供本地平均时间(LMT)偏移量:

>>> pytz.timezone("Europe/Athens")
<DstTzInfo 'Europe/Athens' LMT+1:35:00 STD>
#                          ^^^-------------------- local mean time

然而,当您进行本地化时:
>>> var1 = datetime.datetime(2017,10,25,20,10,50)
>>> var1 = pytz.timezone("Europe/Athens").localize(var1)
>>> var1.tzinfo
<DstTzInfo 'Europe/Athens' EEST+3:00:00 DST>
#                          ^^^^-------------------- eastern european summer time

现在报告了不同的偏移量,这次是基于EEST。

3
tzinfo对于某些时区可能无法正常工作,这可能是错误结果的原因。
pytz文档

不幸的是,使用标准日期时间构造函数的tzinfo参数与pytz在许多时区中“不起作用”。

使用localizeastimezone可以解决此问题。文档指出,“处理时间的首选方法是始终使用UTC进行操作,在生成供人类阅读的输出时仅在转换为本地时间”。

import datetime, pytz
localTimezone = pytz.timezone('Europe/Athens')
var1 = datetime.datetime(2017,10,25,20,10,50,tzinfo=pytz.utc) 
loc_dt = var1.astimezone(localTimezone)
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
print(loc_dt.strftime(fmt))  

这将打印:<\p>
2017-10-25 23:10:50 EEST+0300

1
在第二个代码中,您使用了.localize(),它将一个naive datetime对象解释为该时区中的时间,而不是将时间移动到另一个时区。naive datetime对象没有时区信息,因此无法进行移动。
由于您在第二个代码中使时间本地化,因此第二个代码显示的时间是正确的。而在第一个代码中,由于您没有使时间本地化,因此显示的时间是不正确的。

1
谢谢您的快速回复,您对第二个例子是正确的。但我的问题是第一个例子,而不是第二个。 - Kwnstantinos Nikoloutsos
1
@KwnstantinosNikoloutsos正在解释为什么你在第一个示例中有问题:没有在你的datetime对象上调用localize - Adonis
@Adonis Bingo!我已经编辑了我的答案以包括那个。 - Adi219

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接