Python datetime 解析带时区的时间戳
Python datetime parsing timestamp with 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(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
除非我遗漏了什么,否则我只能得出结论,这条线产生的时间
parsed_time = datetime.fromtimestamp(zoned_time.timestamp(), tz_object)
生成的时间与解析实际 ISO 字符串的时间不同。通常,我希望解析时间的时间戳 return 指代 8:12 的时间戳在分配的时区中。
这种行为是预期的吗?
我错过了什么吗?
如果需要 Python 3.9,请使用 zoneinfo. Note that there is a deprecation shim for pytz。
您的代码可以像
一样正常工作
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
你需要localize
带有时区的日期时间对象; 永远不要直接用 pytz 设置 tzinfo。
我 运行 不久前就遇到过这个问题,其中解析带有时区数据的 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
除非我遗漏了什么,否则我只能得出结论,这条线产生的时间
parsed_time = datetime.fromtimestamp(zoned_time.timestamp(), tz_object)
生成的时间与解析实际 ISO 字符串的时间不同。通常,我希望解析时间的时间戳 return 指代 8:12 的时间戳在分配的时区中。
这种行为是预期的吗? 我错过了什么吗?
如果需要 Python 3.9,请使用 zoneinfo. Note that there is a deprecation shim for pytz。
您的代码可以像
一样正常工作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
你需要localize
带有时区的日期时间对象; 永远不要直接用 pytz 设置 tzinfo。