Python 3.x 带时区的Python datetime解析时间戳

Python 3.x 带时区的Python datetime解析时间戳,python-3.x,datetime,timestamp,timezone,Python 3.x,Datetime,Timestamp,Timezone,不久前,我遇到了这个问题,解析带有时区数据的ISO字符串和解析时间戳(假定是同一时间)将得到不同的结果。我已经编写了一个测试来检查这种行为,它看起来非常不一致: from pytz import timezone as tz from datetime import datetime timezone = "Australia/Sydney" start_time = "2021-05-04T08:12:00" tz_object = tz(timezo

不久前,我遇到了这个问题,解析带有时区数据的ISO字符串和解析时间戳(假定是同一时间)将得到不同的结果。我已经编写了一个测试来检查这种行为,它看起来非常不一致:

from pytz import timezone as tz
from datetime import datetime

timezone = "Australia/Sydney"
start_time = "2021-05-04T08:12:00"
tz_object = tz(timezone)
naive_datetime = datetime.fromisoformat(start_time)


zoned_time = datetime(naive_datetime.year, naive_datetime.month, naive_datetime.day, naive_datetime.hour, naive_datetime.minute, naive_datetime.second, tzinfo=tz_object)
parsed_time = datetime.fromtimestamp(zoned_time.timestamp(), tz_object)

assert zoned_time.time() == naive_datetime.time()
assert zoned_time.time() == parsed_time.time()
此测试产生以下输出

  File "test.py", line 13, in <module>
    assert zoned_time.time() == parsed_time.time()
  AssertionError
正在生成与解析实际ISO字符串不同的时间。通常,我希望解析时间的时间戳返回一个时间戳,该时间戳指的是分配给它的时区中的上午8:12

这是预期的行为吗? 我错过了什么吗?

对于Python 3.9,请使用。请注意,如果需要,有一个弃用垫片

然后,您的代码就可以像

from datetime import datetime
from zoneinfo import ZoneInfo

timezone = "Australia/Sydney"
tz_object = ZoneInfo(timezone)

start_time = "2021-05-04T08:12:00"
naive_datetime = datetime.fromisoformat(start_time)

zoned_time = datetime(naive_datetime.year, naive_datetime.month, naive_datetime.day, naive_datetime.hour, naive_datetime.minute, naive_datetime.second, tzinfo=tz_object)
parsed_time = datetime.fromtimestamp(zoned_time.timestamp(), tz_object)

assert zoned_time.time() == naive_datetime.time()
assert zoned_time.time() == parsed_time.time()
至于为什么会出现断言错误:使用
pytz
时,需要
使用时区对datetime对象进行本地化切勿直接使用pytz设置tzinfo

from datetime import datetime
from zoneinfo import ZoneInfo

timezone = "Australia/Sydney"
tz_object = ZoneInfo(timezone)

start_time = "2021-05-04T08:12:00"
naive_datetime = datetime.fromisoformat(start_time)

zoned_time = datetime(naive_datetime.year, naive_datetime.month, naive_datetime.day, naive_datetime.hour, naive_datetime.minute, naive_datetime.second, tzinfo=tz_object)
parsed_time = datetime.fromtimestamp(zoned_time.timestamp(), tz_object)

assert zoned_time.time() == naive_datetime.time()
assert zoned_time.time() == parsed_time.time()