如何将UTC 13位Unix时间戳转为Python带时区感知的datetime对象?
问题描述
数据库中以UTC时区的13位Unix时间戳存储时间值,在Python中处理时需要生成带时区感知的datetime对象。使用datetime.utcfromtimestamp()转换得到的是无时区感知的naive datetime,后续转换为其他时区时会因本地设备非UTC时区出现计算错误。
示例代码:
>>> from datetime import datetime >>> dt = datetime.utcfromtimestamp(1691868688457/1000) >>> dt.astimezone(pytz.timezone('America/Chicago'))
错误输出结果:
datetime.datetime(2023, 8, 12, 9, 1, 28, 457000, tzinfo=<DstTzInfo 'America/Chicago' CDT-1 day, 19:00:00 DST>)
正确结果应为:
datetime.datetime(2023, 8, 12, 14, 31, 28, 457000, tzinfo=<DstTzInfo 'America/Chicago' CDT-1 day, 19:00:00 DST>)
目前仅能通过手动构造datetime对象的粗糙方式添加时区:
dt = datetime(year=dt.year, month=dt.month, day=dt.day, hour=dt.hour, minute=dt.minute, second=dt.second, microsecond=dt.microsecond, tzinfo=pytz.utc)
询问:是否存在更规范的方式,直接读取时间戳并生成带时区感知的datetime对象?
解决方案
有两种更简洁规范的实现方式,根据Python版本选择:
1. Python 3.9+:使用标准库zoneinfo(推荐)
Python 3.9及以上自带zoneinfo模块,可直接通过datetime.fromtimestamp()指定UTC时区,一步生成带时区感知的对象:
from datetime import datetime from zoneinfo import ZoneInfo # 13位时间戳转换为秒 timestamp = 1691868688457 / 1000 # 直接生成带UTC时区的感知datetime dt_aware = datetime.fromtimestamp(timestamp, tz=ZoneInfo("UTC")) # 转换目标时区 dt_chicago = dt_aware.astimezone(ZoneInfo("America/Chicago"))
2. 兼容旧版本:使用pytz库
若使用Python 3.8及以下,或依赖pytz,可通过两种方式实现:
方式一:用localize()给naive datetime添加时区
from datetime import datetime import pytz timestamp = 1691868688457 / 1000 dt_naive = datetime.utcfromtimestamp(timestamp) # 用pytz推荐的localize方法添加UTC时区 dt_aware = pytz.utc.localize(dt_naive) dt_chicago = dt_aware.astimezone(pytz.timezone('America/Chicago'))
方式二:直接指定时区生成感知对象
from datetime import datetime import pytz timestamp = 1691868688457 / 1000 # 直接生成带UTC时区的感知datetime dt_aware = datetime.fromtimestamp(timestamp, tz=pytz.utc) dt_chicago = dt_aware.astimezone(pytz.timezone('America/Chicago'))
内容的提问来源于stack exchange,提问作者Bubble3D
相关产品推荐
相关产品推荐

