Python datetime和tzinfo对象(更改分钟而不是小时)

时间:2016-11-22 11:10:47

标签: python datetime pytz

我试图将tzinfo应用于日期时间对象。

In [1]: from datetime import datetime
In [2]: import pytz

In [3]: london = pytz.timezone("Europe/London")
In [4]: london
Out[5]: <DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>

In [6]: localized_date_object = datetime(2016, 1, 1, 11, 30, 0, 5000, london)
In [7]: localized_date_object
Out[8]: datetime.datetime(2016, 1, 1, 11, 30, 0, 5000, tzinfo=<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>)

In [9]: utc_date_object = localized_date_object.astimezone(pytz.utc)
In [10]: utc_date_object
Out[11]: datetime.datetime(2016, 1, 1, 11, 31, 0, 5000, tzinfo=<UTC>)

In [16]: paris = pytz.timezone("Europe/Paris")
In [17]: localized_date_object = datetime(2016, 1, 1, 11, 30, 0, 5000, paris)
In [18]: utc_date_object = localized_date_object.astimezone(pytz.utc)
In [19]: utc_date_object
Out[19]: datetime.datetime(2016, 1, 1, 11, 21, 0, 5000, tzinfo=<UTC>)

正如您所看到的,它将delta应用于分钟而不是小时 有人可以解释一下我在这里做错了什么。

5 个答案:

答案 0 :(得分:1)

我认为你应该在巴黎时间使用CET,在伦敦时间使用UTC。 我使用了一些不同的方法,但它对我有用:

from datetime import datetime
from pytz import timezone

ldo = datetime(2016, 1, 1, 11, 30, 0, 5000)
ldo = ldo.replace(tzinfo=timezone('Europe/London'))

udo = ldo.astimezone(timezone('UTC'))
print ldo
print udo

ldo = datetime(2016, 1, 1, 11, 30, 0, 5000)
ldo = ldo.replace(tzinfo=timezone('CET'))

udo = ldo.astimezone(timezone('UTC'))
print ldo
print udo

<强>更新

存储时间值时,还应存储相关的时区信息。 IMO最佳做法是将所有内容存储在UTC中并转换为查看“用户”时区。 BTW从UTC转换到欧洲/巴黎的工作完美无瑕,试试这个:

winter = datetime(2016, 1, 1, 11, 30, 0, 5000, tzinfo=timezone("UTC"))
paris =  winter.astimezone(timezone("Europe/Paris"))
print paris
# 2016-01-01 12:30:00.005000+01:00

summer = datetime(2016, 6, 1, 11, 30, 0, 5000, tzinfo=timezone("UTC"))
paris = summer.astimezone(timezone("Europe/Paris"))
print paris
# 2016-06-01 13:30:00.005000+02:00

答案 1 :(得分:0)

在第5行,它显示了一个奇怪的输出 - <DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>,似乎是一分钟的转变(减1天+ 23:59:00)。

我建议你在pytz中尝试一些其他的时区定义来查看它们的声明。

答案 2 :(得分:0)

时区欧洲/伦敦是在UTC 1分钟之后。欧洲/巴黎时区在UTC之前9分钟。伦敦和巴黎在地理位置上接近格林威治,所以时区偏移很小。

如果您尝试

pytz.timezone("Asia/Shanghai")

,你会看到时间变化。

答案 3 :(得分:0)

pytz文档说:

  

此库仅支持构建本地化时间的两种方式。第一种是使用pytz库提供的localize()方法。这用于本地化原始日期时间(没有时区信息的日期时间):

     

构建本地化时间的第二种方法是使用标准astimezone()方法转换现有的本地化时间:

     

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

在提供的代码示例中,您尝试使用tzinfo参数而不是localize()

>>> london = pytz.timezone("Europe/London")

>>> datetime.datetime(2016, 1, 1, 11, 30, 0, 5000, london) # This is incorrect
datetime.datetime(2016, 1, 1, 11, 30, 0, 5000, tzinfo=<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>)

>>> london.localize(datetime.datetime(2016, 1, 1, 11, 30, 0, 5000)) # This is correct
datetime.datetime(2016, 1, 1, 11, 30, 0, 5000, tzinfo=<DstTzInfo 'Europe/London' GMT0:00:00 STD>)

答案 4 :(得分:0)

根据当时商定的标准化,通常有不止一个关于UTC偏移的定义。

当使用带时区的datatime函数构造日期时间时,对于使用哪种转换不是很聪明,并且倾向于默认使用旧的历史偏移量,在您的示例中为一分钟偏移量。之所以这样做,是因为它在考虑转换日期之前选择了时区增量。

此替代方法可以解决,从而提供更可靠的(现代标准)结果:

dt = mytz.localize(datetime(2020,4,7,16,30))