Pandas 无法识别 TZ 感知日期时间

Pandas not recognizing TZ aware datetime

我正在尝试编写一个脚本,该脚本接受一个日期和 returns 一个 pandas 数据框,其中包含索引的半小时内具有本地化日期时间的零。 SP是指结算周期,为半小时。这些脚本在大多数日子里都运行良好,但当它更改为夏令时或从夏令时更改时,我得到:

AmbiguousTimeError: Cannot infer dst time from '2017-10-29 01:00:00', try using the 'ambiguous' argument

这发生在行:

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

它尝试转换的日期是“2017-10-29 01:00:00”,即使给出的是“2017-10-29 01:00:00 + 1:00:00”,我会吗必须转换为 UTC=0,转换为 pandas,然后再次本地化? 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)   

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

感谢所有回复和帮助!

您的问题源于夏令时的混淆。考虑以下因素:

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

如您所见,您处理的时间点是 "same" 的两倍,但编码不同。

一种解决方案是将所有时间转换为 UTC(没有夏令时),并且仅在需要输出时将时间转换回来。

但是,我认为您在错误的地方添加了 timedelta。考虑

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

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

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

您必须使用

让日期时间对象识别时区
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