python 3.9.1 số học datetime

Dec 03 2020

Trong khi thử hỗ trợ zoneinfo mới trong python3.9.1, tôi nhận thấy rằng sự khác biệt về thời gian của các đối tượng nhận biết datetime khác với các đối tượng do pytz tạo ra như được hiển thị trong đầu ra của chương trình dưới đây:

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

Có vẻ như múi giờ gốc được hỗ trợ bỏ qua thực tế rằng ngày 10 tháng 10 năm 2020 là ngày chuyển đổi từ giờ mùa hè sang giờ mùa đông và do đó thời lượng của ngày đó là 25 giờ. Tôi đang thiếu cái gì?

Trả lời

MrFuppes Dec 03 2020 at 20:11

Một minh họa cho nhận xét của tôi; nhận biết datetime với tzinfothiết lập với ZoneInfo từ zoneinfotrả về thời gian tường timeelta. Nếu bạn làm điều tương tự với ngày giờ đã pytz.timezonebiết, bạn sẽ có được thời gian hoàn toàn chính xác.

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