【问题标题】:Daylight savings transition at wrong time在错误的时间进行夏令时转换
【发布时间】:2013-12-27 10:20:42
【问题描述】:

我有一个没有时区信息的日期列表,但是我知道时区以及它们是本地时间的事实。我想转换为标准时间以执行时区分析

在悉尼夏令时结束于夏令时凌晨 3 点,因此前 5 行应在 +11:00 DST 之前,其余的应该在 +10:00 STD 之前。我得到的结果是第一行是 +11:00 DST,其余的是 +10:00 STD。

鉴于我知道日期列表已排序,是否有内置方法来本地化日期列表。看来您应该知道 is_dst=True 或 is_dst=False 以处理重叠。

问候 戴夫

import pytz

times = [
    datetime(2013,4,7,1,45,0)
    ,datetime(2013,4,7,2,0,0)
    ,datetime(2013,4,7,2,15,0)
    ,datetime(2013,4,7,2,30,0)
    ,datetime(2013,4,7,2,45,0)
    ,datetime(2013,4,7,2,00,0)
    ,datetime(2013,4,7,2,15,0)
    ,datetime(2013,4,7,2,30,0)
]
#
timezone = pytz.timezone('Australia/Sydney')
localized = map(timezone.localize, times)

for t,l in zip(times, localized):
    print(t,l)

【问题讨论】:

  • 你看过 datetime.isoformat() 吗?它可能会对你有所帮助。
  • 不,我会检查的。我已经意识到我可以通过传递 is_dst=True 来实现我想要的,直到我到达凌晨 2:00 的第二个实例,所以我创建了一个解决方法,我在其中循环遍历日期。第一次遇到我设置为 is_dst=True 的日期,第二次设置为 False。

标签: python pytz


【解决方案1】:

timezone.localize 具有默认为 Falseis_dst 参数。它用于不明确或不存在的输入日期。在这种情况下,您可以将其设置为 None 以引发异常。

为什么您仅仅因为列表中的索引与datetime(2013,4,7,2) 不同而期望得到不同的结果?

>>> from datetime import datetime
>>> import pytz
>>> timezone = pytz.timezone('Australia/Sydney')
>>> timezone.localize(datetime(2013,4,7,2))
datetime.datetime(2013, 4, 7, 2, 0,
                  tzinfo=<DstTzInfo 'Australia/Sydney' EST+10:00:00 STD>)
>>> timezone.localize(datetime(2013,4,7,2), is_dst=False)
datetime.datetime(2013, 4, 7, 2, 0,
                  tzinfo=<DstTzInfo 'Australia/Sydney' EST+10:00:00 STD>)
>>> timezone.localize(datetime(2013,4,7,2), is_dst=True)
datetime.datetime(2013, 4, 7, 2, 0,
                  tzinfo=<DstTzInfo 'Australia/Sydney' EST+11:00:00 DST>)
>>> timezone.localize(datetime(2013,4,7,2), is_dst=None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/pytz/tzinfo.py", line 344, in localize
    raise AmbiguousTimeError(dt)
pytz.exceptions.AmbiguousTimeError: 2013-04-07 02:00:00

除非您明确提供is_dst 参数,否则pytz 无法找出datetime(2013,4,7,2) 的时间。

【讨论】:

  • 嗨,对不起,问题不太清楚,我知道结果不会根据索引而改变,我想问是否有一种内置的方式来本地化订购的日期序列,或者我是否必须手动完成。
  • @user2981639:一般没有“内置”方式,否则不需要传递is_dst 参数(它会自动计算)。想象一下您列表中的所有值都产生AmbiguousTimeError,您期望在这种情况下得到什么结果?当然,如果它不是任意日期列表,那么可能会有特定的解决方案
  • 是的,我已经意识到,我的数据按固定间隔(通常是 15 或 30 分钟)进行排序
【解决方案2】:

这是我想出的解决方案,数据是排序的,所以我第一次遇到模棱两可的时候设置is_dst=True,第二次设置False。此外,如果遇到不存在的时间,我会重置 is_dst

seen = set()

get_datetime = operator.itemgetter('datetime')
for row in data:
    dt = get_datetime(row)

    try:
        localized = timezone.localize(dt, is_dst=None)
    except pytz.NonExistentTimeError:
        localized = timezone.localize(dt, is_dst=True)
        seen = set()
    except pytz.AmbiguousTimeError:
        localized = timezone.localize(dt, is_dst=(dt not in seen)) 
        seen.add(dt)

【讨论】:

    猜你喜欢
    • 2018-03-28
    • 2011-12-22
    • 2017-08-28
    • 1970-01-01
    • 2018-04-12
    • 2016-08-10
    • 2021-10-18
    • 2014-06-11
    • 2021-03-09
    相关资源
    最近更新 更多