我在与pytz的.localize()函数的一些奇怪的问题。 有时,它不会作出调整,以本地化的日期时间:
.localize行为:
>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>
>>> d
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421)
>>> tz.localize(d)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421,
tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)
>>> tz.normalize(tz.localize(d))
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421,
tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)
正如你所看到的,时间尚未改变本地化的结果/标准化操作。 但是,如果.replace使用:
>>> d.replace(tzinfo=tz)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421,
tzinfo=<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>)
>>> tz.normalize(d.replace(tzinfo=tz))
datetime.datetime(2009, 9, 2, 15, 1, 42, 91421,
tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)
这似乎使调整到日期时间。
问题是 - 这是正确的,为什么其他人的错吗?
localize
只是假设你通过它天真的日期时间是“正确”的(除了不知道有关的时区!),因此只需设置时区,没有其他调整。
你可以(和它的最好...)内部在UTC(而不是天真的日期时间)工作,并使用replace
当你需要执行我的日期时间/ O在本地化的方式( normalize
将处理DST等)。
localize
是使用用于与初始固定日期时间值创建日期时间感知对象的正确功能。 所得的日期时间知晓对象将有原来的日期时间值。 在我看来,一个非常普遍的使用模式,和一个也许pytz可以更好地记录。
replace(tzinfo = ...)
不幸命名。 这是一个函数,其行为是随机的。 我会建议避免使用这个功能来设置时区,除非你喜欢自找痛苦。 我已经使用此功能吃尽苦头。
我知道我是一个有点晚于这个......但这里是我发现工作得很好。 在UTC工作亚历克斯说:
tz = pytz.timezone('Africa/Abidjan')
now = datetime.datetime.utcnow()
然后本地化:
tzoffset = tz.utcoffset(now)
mynow = now+tzoffset
而这种方法不完全处理DST
这DstTzInfo类用于时区,其中从UTC的变化在时间上错开在某些点。 例如(如你可能知道),许多地方过渡到夏末“夏令时”在夏季的开始,然后再返回到“标准时间”。 每个DstTzInfo实例仅代表这些时区之一,但“本土化”和“正常化”的方法帮助你得到正确的实例。
阿比让,有只去过一个过渡(根据pytz),那是在1912年:
>>> tz = pytz.timezone('Africa/Abidjan')
>>> tz._utc_transition_times
[datetime.datetime(1, 1, 1, 0, 0), datetime.datetime(1912, 1, 1, 0, 16, 8)]
该TZ对象,我们走出pytz的代表1912年的前区:
>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>
现在,在你的两个例子往上看,看到当你调用tz.localize(d)你没有得到这个前1912年时区添加到您的天真的DateTime对象。 它假定DateTime对象,你给它代表了正确的时区的本地时间 ,这是后1912年时区本地时间。
然而,在使用d.replace您的第二个例子(tzinfo = TZ),它需要你的日期时间对象来表示在预1912时区的时间。 这可能不是你的意思。 然后当你调用dt.normalize它这个转换为在该日期时间价值是正确的,即后-1912时区的时区。