熊猫无法识别TZ知道的日期时间

时间:2018-07-04 11:54:49

标签: python pandas datetime dst pytz

我正在尝试编写一个脚本,该脚本接受一个日期并返回一个包含零的熊猫数据框,该数据框在半小时内为索引提供了本地化的日期时间。 SP是指半小时的结算期。这些脚本在大多数情况下都能很好地工作,但是当更改为夏令时或从夏令时更改时,我会得到:

  

AmbiguousTimeError:无法从'2017-10-29 01:00:00'推断出夏时制,请尝试使用'ambiguous'参数

这发生在以下行:

df_datetime.at[datetime, "Generation"] = 0

它尝试转换的日期是'2017-10-29 01:00:00',即使它被赋予'2017-10-29 01:00:00 + 1:00:00',我也必须转换为UTC = 0,转换为熊猫然后再次本地化? 2017年10月29日是英国夏令时结束的日子。

完整脚本如下:

import pandas as pd
from datetime import datetime, timedelta
import pytz


def SP_to_time_delta(SP):
    dec_hour = (SP - 1)/2

    hour = int(dec_hour)
    if abs(int(dec_hour)-dec_hour) == 0.5:
        minute = 30
    else:
        minute = 0

    SP_timedelta = timedelta(hours=hour, minutes=minute)
    return SP_timedelta

def localize_datetime_UK(date, SP):
    pytz_tz = pytz.timezone('Europe/London')
    local_date = pytz_tz.localize(date)
    SP_timedelta = SP_to_time_delta(SP)

    local_datetime = local_date+SP_timedelta
    return local_datetime    

def get_datetime_df(SettlementDate, max_SP):
    df_datetime = pd.DataFrame([])
    for i in range(max_SP+1):
        datetime = localize_datetime_UK(SettlementDate, i)
        df_datetime.at[datetime, "Generation"] = 0
    df_datetime = df_datetime.sort_index()
    return df_datetime    

SettlementDate = datetime(2017, 10, 29) 
df_datetime = get_datetime_df(SettlementDate, 50)   

解决此问题的最佳方法是什么?

感谢所有答复和帮助!

1 个答案:

答案 0 :(得分:1)

您的问题源于夏令时的混乱。请考虑以下内容:

import pandas as pd
from datetime import datetime, timedelta
import pytz

pytz_tz = pytz.timezone('Europe/London')

datetime_1 = pytz_tz.localize(datetime(2017, 10, 29) \
             + timedelta(hours=0, minutes=0))
datetime_2 = pytz_tz.localize(datetime(2017, 10, 29) \
             + timedelta(hours=1, minutes=0))

print(datetime_1)
print(datetime_2)

> 2017-10-29 00:00:00+01:00
> 2017-10-29 01:00:00+00:00

如您所见,您正在处理两次“相同”时间点,但使用不同的编码。

一种解决方案是将所有时间都转换为UTC(没有dst),而仅在需要输出时才将时间转换回去。

但是,我认为您在错误的位置添加了时间增量。考虑

datetime_1 = pytz_tz.localize(datetime(2017, 10, 29)) \  # localize first
             + timedelta(hours=0)  # then add the delta
datetime_2 = pytz_tz.localize(datetime(2017, 10, 29)) \ # localize first
             + timedelta(hours=1)  # then add the delta

> 2017-10-29 00:00:00+01:00
> 2017-10-29 01:00:00+01:00

产生独特的结果。检查应用哪个版本的应用程序的语义。

=====旧答案======

您必须使用以下命令使datetime对象时区为已知

from datetime import datetime, timedelta
from pytz import timezone
import pytz

eastern = timezone('US/Eastern')
SelltementDate = eastern.localize(datetime(2017, 10, 29, 0, 0, 0))

另请参阅documentation of pytz