在python开发中获取当前时间是非常常见的操作,但默认的time.time()返回的是秒级浮点数,很多场景下我们需要更精确的毫秒级时间,比如生成请求签名、记录日志时间戳、统计代码执行耗时、做分布式ID生成等。本文将详细介绍python中获取毫秒级时间的几种常用方法,分析它们的原理、精度差异以及各自的适用场景,帮助你在实际项目中做出正确选择。

一、使用time模块获取毫秒级时间戳
time.time()是python中最常用的获取当前时间的方法,它返回从1970年1月1日零点到现在的秒数,类型是浮点数。小数部分就是不足一秒的精度,因此最直接的思路就是把它乘以1000再取整,得到毫秒级的时间戳。
import time # 方式一:time.time() 乘以1000后取整 millis = int(time.time() * 1000) print(millis) # 输出类似 1718179200123 # 方式二:直接获取纳秒精度再换算(python 3.7+) millis_ns = time.time_ns() // 1_000_000 print(millis_ns)
这里推荐优先使用time.time_ns(),它是python 3.7引入的函数,直接返回纳秒级整数,不存在浮点数精度丢失问题。time.time()返回的是float类型,float的小数位只有约15到16位有效数字,秒级时间戳的整数部分已经占了10位,剩余能表示毫秒的小数位虽然够用,但在更精细的场景下可能出现尾数不准的情况。而time.time_ns()全程使用整数运算,用整除的方式换算成毫秒,结果绝对可靠。
需要特别注意的是操作系统对精度的影响。在Linux和macOS系统上,time.time()底层调用的是高精度时钟,毫秒级数据基本准确;但在较旧版本的Windows系统上,time.time()的精度可能只有15.6毫秒左右,这意味着连续调用两次time.time()可能得到完全相同的结果。如果你的程序需要部署到Windows平台,务必使用time.time_ns()或下面介绍的其他方案来规避这个问题。
二、使用datetime模块获取毫秒并格式化输出
时间戳虽然方便计算,但可读性很差,无法直接看出具体日期时间。datetime模块可以生成带毫秒的可读时间字符串,适合用在日志记录、文件命名等场景。
from datetime import datetime
# 获取当前时间并格式化,%f表示微秒
now = datetime.now()
formatted = now.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
print(formatted) # 输出类似 2024-06-12 15:30:45.123
# 从datetime对象反向计算毫秒时间戳
timestamp_ms = int(now.timestamp() * 1000)
print(timestamp_ms)strftime中的%f格式符输出的是微秒,一共6位数字,所以代码中用[:-3]切片去掉最后三位,剩下的正好是毫秒。这个写法在日志系统中非常实用,比如结合logging模块输出精确到毫秒的日志时间。
另外一种常见需求是把毫秒时间戳转换回可读时间,这在处理前端传来的数据或数据库中存储的时间戳时经常遇到。做法是先把毫秒除以1000转成秒,再用datetime.fromtimestamp()转换:
from datetime import datetime
ts_ms = 1718179200123
dt = datetime.fromtimestamp(ts_ms / 1000)
print(dt.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])datetime方式的优点是输出直观、可以灵活定制格式,缺点是需要额外的转换步骤,如果只需要纯数字时间戳用于计算或比较,还是time模块更简洁高效。
三、测量代码执行耗时为什么不要用time.time
很多人拿到毫秒时间戳后,会顺手用它来统计某段代码的执行耗时:先记录开始时间,执行完毕再记录结束时间,两者相减。这种做法在粗粒度场景下没问题,但如果被测代码执行时间只有几毫秒甚至更短,就可能出现耗时为零或负数的诡异结果。
原因主要有两个:一是前面提到的系统时钟精度限制;二是time.time()获取的是墙上时钟,也就是系统当前的真实时间,而系统时间可能被NTP服务同步、被用户手动修改。一旦在测量过程中时钟被调整,计算出的耗时就完全不可信了。
正确的做法是使用time.perf_counter(),它是专门为性能测量设计的高精度计数器,使用单调时钟,不受系统时间被修改的影响,精度可以达到微秒甚至纳秒级:
import time
start = time.perf_counter()
# 模拟一段耗时操作
total = 0
for i in range(1_000_000):
total += i
end = time.perf_counter()
elapsed_ms = (end - start) * 1000
print(f'耗时 {elapsed_ms:.3f} 毫秒')python 3.7之后还可以用time.perf_counter_ns()获得纳秒整数,避免浮点运算。对于更正式的性能分析,标准库还提供了timeit模块,它能自动多次执行代码并排除干扰因素,统计结果更加科学。总结一下选择原则:记录业务发生的时间用time.time_ns(),测量代码跑得多快用time.perf_counter(),两者不要混用。
四、常见应用场景与避坑要点
结合实际项目经验,最后整理几个毫秒级时间的典型用法和容易踩的坑。第一个场景是接口签名,很多API要求请求参数中带上毫秒时间戳做防重放校验,直接用str(int(time.time() * 1000))即可;第二个场景是生成唯一ID或订单号,可以把毫秒时间戳作为前缀拼接随机数;第三个场景是日志和埋点上报,毫秒精度能帮助还原事件的先后顺序。
import time
import random
# 生成带毫秒时间戳的订单号示例
def generate_order_id():
ts = time.time_ns() // 1_000_000
rand = random.randint(1000, 9999)
return f'ORD{ts}{rand}'
print(generate_order_id())坑点方面,第一要注意时区问题,time.time()返回的是UTC时间戳,本身不带时区,转换成本地时间时才需要考虑时区,跨服务器部署时建议统一存储UTC时间戳;第二要注意取整方式的差异,int()是直接截断小数,如果业务要求四舍五入应该使用round();第三要注意python 2早已停止维护,time_ns系列函数只在python 3.7及以上版本可用,维护老项目时需先确认版本。
总的来说,python获取毫秒级时间的核心方案就三种:time.time()乘1000最简单通用,time.time_ns()精度最可靠,datetime格式化最适合展示给用户看。根据实际需求选对方法,既能保证精度,又能让代码简洁易读。
python毫秒级时间time.time时间戳修改时间:2026-09-05 04:52:29