timedelta对象不考虑夏令时

问题描述 投票:0回答:1

我正在尝试获取适当的时间范围,以在用户本地时区的数据库(日期时间存储在UTC中)中进行查询。这是我发现的一些奇怪行为,我不知道该如何解决:

import pytz
from datetime import datetime, timedelta

local_tz = pytz.timezone("America/New_York")
utc = pytz.timezone("UTC")

start = local_tz.localize(datetime(2019, 11, 3))  # 2019-11-03 00:00:00-04:00
end = start + timedelta(days=1)  # 2019-11-04 00:00:00-04:00

start_utc = utc.normalize(start)  # 2019-11-03 04:00:00+00:00
end_utc = utc.normalize(end)  # 2019-11-04 04:00:00+00:00

utc.normalize(local_tz.localize(datetime(2019, 11, 4)))  # 2019-11-04 05:00:00+00:00

[归一化通过将end对象添加到timedelta而构成的start变量时,夏令时的更改会丢失。为什么会发生这种情况?

python datetime timezone dst
1个回答
1
投票

不确定日期时间计算的预期行为,但是我仅从共享代码示例中解释行为。

pytz.localize创建一个时区感知日期时间实例。当将NY时区用于localize原始日期时间时,它将分配正确的时区,即EDT直到11月3日,以及EST代表11月4日及以后。让我们在此处排除timedelta

>>> import pytz
>>> from datetime import datetime, timedelta
>>> tz_ny = pytz.timezone("America/New_York")
>>> tz_ny.localize(datetime(2019, 11, 3))
datetime.datetime(2019, 11, 3, 0, 0, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)
>>> tz_ny.localize(datetime(2019, 11, 4))
datetime.datetime(2019, 11, 4, 0, 0, tzinfo=<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)

正如人们所期望的,DstTzInfo不同,因为纽约夏令时于11月3日结束。

共享代码示例在11月3日start之前创建localizing,该操作将EDT作为tzinfo分配给日期时间对象(使用DST)。要创建end,将1天的timedelta添加到start,但是tzinfo对象的datetimekept untouched

>>> start = tz_ny.localize(datetime(2019, 11, 3))
>>> start.tzinfo
<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>
>>> end = start + timedelta(days=1)
>>> end.tzinfo
<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>

因此end是11月4日的datetime,但DstTzInfo信息仍然与11月3日相同。这与11月4日未使用DST的localizing天真datetime不同。

© www.soinside.com 2019 - 2024. All rights reserved.