Python 时间戳和日期怎么互转:10 位、13 位和时区问题一次讲清
讲清 Python 中秒级时间戳、毫秒级时间戳、datetime、时区、本地时间和 UTC 的转换方法,适合日志排查、接口调试和数据处理。
相关工具
先分清 10 位和 13 位时间戳
时间戳是程序里表示时间点的一种方式。常见 Unix 时间戳以 1970-01-01 00:00:00 UTC 为起点,记录到某个时间经过了多少秒或毫秒。10 位时间戳通常是秒级,比如 1720953600;13 位时间戳通常是毫秒级,比如 1720953600000。
如果把 13 位毫秒时间戳当成秒处理,结果会跑到非常遥远的未来;如果把 10 位秒级时间戳当成毫秒处理,结果会变成 1970 年附近。这是接口调试和日志排查里最常见的时间问题。看到一个时间戳,第一步不是直接转换,而是先判断它的位数和单位。
在 Python 里,datetime.fromtimestamp 默认接收的是秒。如果你拿到的是 13 位毫秒时间戳,要先除以 1000。这个小动作很重要,不然你会得到完全错误的日期。
时间戳转日期的基础写法
秒级时间戳转本地时间可以这样写:
from datetime import datetime
ts = 1720953600
dt = datetime.fromtimestamp(ts)
print(dt.strftime('%Y-%m-%d %H:%M:%S'))如果是毫秒级时间戳,先除以 1000:
ts_ms = 1720953600000
dt = datetime.fromtimestamp(ts_ms / 1000)
print(dt.strftime('%Y-%m-%d %H:%M:%S'))strftime 用来把 datetime 格式化成你想要的字符串。常用格式是 %Y-%m-%d %H:%M:%S。注意 fromtimestamp 使用的是本地时区。如果你的电脑、服务器或运行环境时区不同,显示结果也可能不同。
日期转时间戳怎么写
如果你有一个日期字符串,想转成时间戳,可以先用 strptime 解析,再调用 timestamp:
from datetime import datetime
text = '2026-07-14 09:30:00'
dt = datetime.strptime(text, '%Y-%m-%d %H:%M:%S')
print(int(dt.timestamp()))
print(int(dt.timestamp() * 1000))strptime 的格式必须和字符串一致。比如日期里只有年月日,就用 %Y-%m-%d;如果有斜杠,就要写 %Y/%m/%d。很多解析失败都是格式不匹配,而不是时间本身有问题。
timestamp 返回的是秒级浮点数,乘以 1000 后可以得到毫秒级。日常接口里,如果字段名是 createdAt、expireAt,不一定能看出单位,最好看文档。如果没有文档,就看数字位数并用时间戳工具验证。
UTC 和本地时间不要混着用
时间戳本身通常表示绝对时间点,但日期字符串经常带有时区含义。UTC 时间和北京时间相差 8 小时。如果服务端存 UTC,前端展示北京时间,这是很常见的设计。但排查问题时,如果你不知道当前显示的是哪个时区,就很容易误判。
Python 里可以使用 timezone 明确时区:
from datetime import datetime, timezone, timedelta
beijing = timezone(timedelta(hours=8))
dt = datetime.fromtimestamp(1720953600, tz=beijing)
print(dt.strftime('%Y-%m-%d %H:%M:%S %z'))如果你的项目涉及海外用户、服务器部署在国外、日志系统使用 UTC,就不要只依赖本地时间。建议在日志和接口里保留原始时间戳,同时在展示层转换成本地时间。这样排查问题时更稳。
接口和日志里的时间问题怎么排查
接口返回时间不对时,先看原始值。它是数字还是字符串?是 10 位还是 13 位?字段名有没有 ms、Millis、timestamp、datetime 之类提示?然后用 Python 和在线时间戳工具分别转换,确认结果是否一致。
日志排查时,要同时记录几个信息:原始时间戳、转换后的本地时间、转换后的 UTC 时间、服务器所在时区。不要只截图一个显示时间,因为它可能已经被某个系统转换过。尤其是定时任务、优惠券过期、订单关闭、缓存失效这类问题,时区和单位都很关键。
如果你发现时间差刚好是 8 小时,优先怀疑 UTC 和北京时间转换。如果差距特别大,优先怀疑秒和毫秒混用。如果差距是几分钟或几秒,可能是服务器时间不同步、请求延迟或业务处理时间。
还有一种情况是日期字符串没有写时区。比如 2026-07-14 09:30:00 这句话本身并没有说明它是北京时间、UTC 还是服务器本地时间。不同系统按不同默认时区解析,就会得到不同时间戳。正式接口里更推荐使用 ISO 8601 格式,或者直接传时间戳,并在文档里明确单位和时区。
一套实用写法建议
写脚本时,可以封装一个自动判断 10 位和 13 位的函数:
from datetime import datetime
def parse_timestamp(value):
value = int(value)
if value > 10_000_000_000:
value = value / 1000
return datetime.fromtimestamp(value)这个函数不复杂,但能减少很多低级错误。真正严谨的项目仍然应该依赖接口文档,而不是只靠位数猜测。位数判断适合调试和临时脚本,正式代码最好明确字段单位。
批量处理数据时,也建议在输出里保留原始时间字段。比如新增 created_at_text 字段用于阅读,但不要删除 created_at_timestamp。这样后续发现转换规则有误时,还能根据原始值重新处理,不必回头找原始文件。
工具帮的时间戳工具适合做人工核对。你可以把接口返回的时间戳先放进工具里看一眼,再写 Python 代码转换。对于新手来说,先用工具确认预期结果,再写代码实现,会比直接在代码里猜更稳。
常见问题
Python fromtimestamp 接收秒还是毫秒?
默认接收秒。13 位毫秒时间戳需要先除以 1000。
为什么转换结果差 8 小时?
通常是 UTC 和北京时间混用导致的。需要确认服务端、客户端和日志系统的时区。
日期字符串转时间戳报错怎么办?
检查 strptime 的格式是否和字符串完全一致,包括分隔符、秒数和空格。