【问题标题】:python 3.9.1 datetime arithmeticpython 3.9.1 日期时间算法
【发布时间】:2021-03-15 11:54:32
【问题描述】:

在尝试 python3.9.1 中的新 zoneinfo 支持时,我注意到 datetime 感知对象的时差与 pytz 产生的时差不同,如下程序的输出所示:

import datetime,zoneinfo,pytz
from sys import version_info
print(f'Python{version_info.major}.{version_info.minor}{version_info.micro}'
f' pytz{pytz.__version__}')
Athens=zoneinfo.ZoneInfo('Europe/Athens')
f='%Y-%m-%d %H:%M:%S'
d=[datetime.datetime.strptime('2020-10-25 00:00:00',f),
   datetime.datetime.strptime('2020-10-25 23:59:59',f)]
print('naive   ',d[1]-d[0])
d=[x.astimezone(Athens) for x in d]
print('zoneinfo',d[1]-d[0])
d=[datetime.datetime.strptime('2020-10-25 00:00:00',f),
   datetime.datetime.strptime('2020-10-25 23:59:59',f)]
athens=pytz.timezone('Europe/Athens')
print('pytz as ',d[1].astimezone(athens)-d[0].astimezone(athens))
print('pytz loc',athens.localize(d[1])-athens.localize(d[0]))

Python3.91 pytz2020.4
naive    23:59:59
zoneinfo 23:59:59
pytz as  1 day, 0:59:59
pytz loc 1 day, 0:59:59

似乎本地时区支持忽略了 2020 年 10 月 25 日是从夏令时转换为冬令时这一事实,因此这一天的持续时间为 25 小时。 我错过了什么?

【问题讨论】:

  • 经过仔细检查,我认为this 是您所缺少的。您从具有 zoneinfo tzinfo 的感知日期时间获得的 timedelta 是“DST 感知”;它显示墙上的时间。顺便说一句,dateutil 也是如此。对于 pytz 的时区,情况似乎并非如此。好痛^^
  • @MrFuppes,谢谢。我需要考虑一下。
  • 我希望这会有所帮助。另请注意Paul's answer 链接的问题以及我在 cmets 中与他进行的讨论。我仍然觉得这整个“墙上时间增量”的东西很难掌握。我喜欢从物理意义上考虑时间,但在现实世界中这可能太天真了^^
  • @MrFuppes,他的情况很好,但没有说服力。反直觉有时只是错误的委婉说法。记录错误并不能使其成为一项功能。

标签: datetime python-3.9


【解决方案1】:

我的评论的插图;使用来自zoneinfo 的 ZoneInfo 设置 tzinfo 的感知日期时间返回一个挂壁时间时间增量。如果您对 pytz.timezone 感知日期时间执行相同操作,您将获得绝对时间时间增量。

from datetime import datetime
from zoneinfo import ZoneInfo
import pytz
from sys import version_info

print(f'Python {version_info.major}.{version_info.minor}{version_info.micro} pytz {pytz.__version__}')
# Python 3.90 pytz 2020.4

d=[datetime.fromisoformat('2020-10-25 00:00:00'), datetime.fromisoformat('2020-10-25 23:59:59')]

Athens = ZoneInfo('Europe/Athens')
print('wall time diff, zoneinfo:', d[1].replace(tzinfo=Athens)-d[0].replace(tzinfo=Athens))
# wall time diff, zoneinfo: 23:59:59

athens = pytz.timezone('Europe/Athens')
print('absolute time diff, pytz:', athens.localize(d[1])-athens.localize(d[0]))
# absolute time diff, pytz: 1 day, 0:59:59

# to get absolute time delta with zoneinfo:
utc = ZoneInfo('UTC')
print('absolute time diff, zoneinfo:', d[1].replace(tzinfo=Athens).astimezone(utc)
                                      -d[0].replace(tzinfo=Athens).astimezone(utc))
# absolute time diff, zoneinfo: 1 day, 0:59:59

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2019-03-04
    • 2012-02-04
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    相关资源
    最近更新 更多