专题:Python标准库精讲系统学习
关键词:Python, 标准库, time, 时间戳, sleep, strftime, perf_counter, struct_time, localtime, gmtime
一、time模块概述
time模块是Python标准库中提供时间访问与转换的核心模块,位于import time之后即可使用,无需额外安装。它围绕操作系统提供的时间函数构建了统一的接口,是Python所有时间日期操作的基础层模块。
time模块主要处理两类时间概念:"真实时间"(wall-clock time)和"处理器时间"(processor time)。真实时间指我们日常生活中流逝的时间(即钟表时间),而处理器时间则衡量CPU执行特定进程所花费的"嘀嗒"数,二者在程序性能测量场景下有着截然不同的用途。
与datetime模块的关系:time模块位于更底层,直接对接C标准库的time.h。而datetime模块则在此基础上提供了更高层次、面向对象的日期时间和时区处理能力。在只需要处理时间戳、简单格式化和延迟操作时,time模块更加轻量和高效;而当需要复杂的日期算术、时区转换或人性化的时间段表示时,则优先选用datetime模块。两个模块通过struct_time作为桥梁可以互相转换。
核心理解:time模块是Python时间体系的基石,所有其他时间日期模块(datetime、calendar)在底层都依赖于time模块提供的能力。掌握time模块,等于掌握了Python时间编程的根基。
导入方式
import time # 标准导入方式
# 之后可以使用 time 模块中的所有函数
current_time = time.time()
print(f"当前时间戳: {current_time}")
模块核心功能一览
| 功能类别 | 核心函数/对象 | 简要说明 |
| 时间戳获取 | time(), time_ns() | 获取当前时间(秒/纳秒级浮点数/整数) |
| 时间元组转换 | gmtime(), localtime(), mktime() | 在时间戳与struct_time之间互转 |
| 格式化与解析 | strftime(), strptime(), asctime(), ctime() | 时间与字符串之间的格式化和解析 |
| 睡眠与延迟 | sleep() | 使当前线程暂停执行指定秒数 |
| 高精度计时 | monotonic(), perf_counter(), process_time() | 用于程序性能测量和基准测试 |
| 时区信息 | timezone, tzname, daylight | 获取本地时区偏移和夏令时信息 |
二、时间戳获取
时间戳(timestamp)是time模块中最基础的概念,指从协调世界时(UTC)1970年1月1日0时0分0秒到当前时刻经过的秒数(不考虑闰秒),也就是计算机领域广为人知的"Unix纪元"(Epoch)。大多数现代操作系统都使用这一标准来记录和传递时间。
2.1 time() — 秒级时间戳
time.time()返回一个浮点数,表示自Epoch以来的秒数。精度取决于操作系统,通常精确到微秒级。
import time
# 获取当前时间戳(浮点数,单位:秒)
ts = time.time()
print(f"时间戳: {ts}")
print(f"整数部分(秒): {int(ts)}")
print(f"小数部分(微秒): {ts - int(ts):.6f}")
# 输出示例:
# 时间戳: 1746489600.123456
# 整数部分(秒): 1746489600
# 小数部分(微秒): 0.123456
函数名的由来:在类Unix系统中,time()是最古老也最通用的系统调用之一,Python沿用了这一命名,保持了与底层C语言函数的一致性。
2.2 time_ns() — 纳秒级时间戳(Python 3.7+)
从Python 3.7开始,time模块引入了time_ns()函数,以整数形式返回纳秒级的时间戳。相比于time()返回的浮点数可能存在精度损失的问题,time_ns()以Python整数返回,提供了纳秒精度且无舍入误差。
import time
# 纳秒级时间戳(整数)
ts_ns = time.time_ns()
print(f"纳秒时间戳: {ts_ns}")
print(f"对应秒数: {ts_ns / 1_000_000_000:.9f}")
# 精度对比:time() 存在浮点精度损失
ts_sec = time.time()
ts_ns2 = time.time_ns()
print(f"time() 的微秒部分: {(ts_sec % 1) * 1_000_000}")
print(f"time_ns() 的微秒部分: {(ts_ns2 % 1_000_000_000) / 1_000}")
# 注意:两次调用存在微小时间差,此处仅为演示概念
最佳实践:如果只需要秒级精度(如日志时间戳),使用time()即可。如果需要高精度计时或避免浮点误差,应使用time_ns()。注意time_ns()返回的是整数纳秒,除以1_000_000_000可转换为秒。
三、struct_time时间元组
struct_time是time模块中用于表示"可分解时间"的核心数据结构。它将一个时间点拆解为年、月、日、时、分、秒等9个字段的命名元组(named tuple),既可以通过索引访问,也可以通过属性名称访问。它是时间戳与格式化字符串之间的关键桥梁。
3.1 struct_time的9个字段
| 索引 | 属性名 | 含义 | 取值范围 |
| 0 | tm_year | 年份 | 如 2026 |
| 1 | tm_mon | 月份 | 1 ~ 12 |
| 2 | tm_mday | 月中的第几天(日期) | 1 ~ 31 |
| 3 | tm_hour | 小时(24小时制) | 0 ~ 23 |
| 4 | tm_min | 分钟 | 0 ~ 59 |
| 5 | tm_sec | 秒 | 0 ~ 61(兼容闰秒,通常为 0 ~ 59) |
| 6 | tm_wday | 一周中的第几天 | 0 ~ 6(0 = 周一) |
| 7 | tm_yday | 一年中的第几天 | 1 ~ 366 |
| 8 | tm_isdst | 夏令时标志 | 0 = 非夏令时, 1 = 夏令时, -1 = 未知 |
注意:tm_wday以周一为0(而非周日),这与许多文化和编程习惯不同,容易出错。tm_sec的取值范围允许到61是为了兼容"闰秒"(leap second),但实际应用中极少出现。
3.2 创建和访问struct_time
import time
# 通过 localtime() 获取当前时间的 struct_time
t = time.localtime()
print(f"类型: {type(t)}")
# 通过索引访问
print(f"年: {t[0]}, 月: {t[1]}, 日: {t[2]}")
print(f"时: {t[3]}, 分: {t[4]}, 秒: {t[5]}")
# 通过属性名访问(推荐,语义更清晰)
print(f"年份: {t.tm_year}")
print(f"月份: {t.tm_mon}")
print(f"日期: {t.tm_mday}")
print(f"星期几(0=周一): {t.tm_wday}")
print(f"年中第几天: {t.tm_yday}")
print(f"夏令时: {t.tm_isdst}")
# struct_time 支持解包
year, month, day, hour, minute, sec, wday, yday, isdst = t
3.3 手动构造struct_time
除了由时间转换函数生成外,也可以使用time.struct_time直接构造。构造时传入包含9个元素的序列(元组或列表)即可。
import time
# 手动构造一个 struct_time
custom_t = time.struct_time((2026, 5, 1, 10, 30, 0, 3, 121, 0))
# (年, 月, 日, 时, 分, 秒, 周几, 年第几天, 夏令时)
# 2026-05-01 是周五,周索引为 3(0=周一)
print(f"自定义时间: {custom_t}")
# 然后可以将其转换为时间戳
ts = time.mktime(custom_t)
print(f"对应时间戳: {ts}")
print(f"验证回转: {time.localtime(ts)}")
四、时间转换函数
time模块提供了4个核心的时间转换函数,用于在时间戳和struct_time之间进行双向转换。这些函数是整个模块的数据枢纽,理解它们的差异能够避免许多棘手的时区相关Bug。
4.1 gmtime() — 转换为UTC时间
time.gmtime([secs])将给定的时间戳(秒数)转换为UTC(协调世界时)下的struct_time。如果不传参数或传None,则使用当前时间。
import time
# 获取当前 UTC 时间
utc_now = time.gmtime()
print(f"UTC 时间: {utc_now}")
# 手动转换特定时间戳
ts = 1746489600.0
utc_time = time.gmtime(ts)
print(f"时间戳 {ts} 的 UTC 时间:")
print(f" {utc_time.tm_year}-{utc_time.tm_mon:02d}-{utc_time.tm_mday:02d} "
f"{utc_time.tm_hour:02d}:{utc_time.tm_min:02d}:{utc_time.tm_sec:02d}")
# 传 0 查看 Unix 纪元
epoch = time.gmtime(0)
print(f"Unix 纪元: {epoch}")
4.2 localtime() — 转换为本地时间
time.localtime([secs])将时间戳转换为本地时区下的struct_time。它会自动应用操作系统的时区设置和夏令时规则。localtime是日常开发中使用频率最高的时间转换函数。
import time
# 获取当前本地时间
local_now = time.localtime()
print(f"本地时间: {local_now}")
# 对比 UTC 和本地时间的差异
ts = time.time()
utc = time.gmtime(ts)
local = time.localtime(ts)
utc_tuple = (utc.tm_year, utc.tm_mon, utc.tm_mday,
utc.tm_hour, utc.tm_min, utc.tm_sec)
local_tuple = (local.tm_year, local.tm_mon, local.tm_mday,
local.tm_hour, local.tm_min, local.tm_sec)
print(f"UTC : {utc_tuple}")
print(f"Local: {local_tuple}")
print(f"时差: {local.tm_hour - utc.tm_hour} 小时")
4.3 mktime() — struct_time转时间戳
time.mktime(t)是localtime()的逆函数——它将一个表示本地时间的struct_time转换为时间戳(浮点数)。这是与gmtime()而非localtime()配对的容易混淆之处:mktime始终将输入解释为本地时间。
import time
# 将 struct_time 转换为时间戳
t = (2026, 5, 5, 10, 30, 0, 0, 125, 0) # 本地时间
ts = time.mktime(t)
print(f"struct_time -> 时间戳: {ts}")
# 验证转换:将时间戳转回 struct_time
back = time.localtime(ts)
print(f"验证回转: {back}")
# 注意:mktime 以本地时间为准
utc_t = time.gmtime(0) # UTC 纪元
# 但 mktime 将其解释为本地时间,结果不是 0
ts_local_epoch = time.mktime(utc_t)
print(f"UTC纪元被 mktime 解读为本地时间: {ts_local_epoch}")
# 实际上应该是:-time.timezone(或考虑夏令时)
重要区别:gmtime()和localtime()对应的是从时间戳到struct_time的正向转换,而mktime()是反向转换。但mktime()总是将输入视为"本地时间",不存在"UTC版本的mktime"——如果需要将UTC的struct_time转时间戳,应使用calendar模块的calendar.timegm()。
五、格式化与解析
在真实世界中,时间戳和struct_time都不便于人类阅读。time模块提供了两套格式化工具:一套是高度可控的strftime/strptime,另一套是快速简易的asctime/ctime。
5.1 strftime() — struct_time转格式化字符串
time.strftime(format[, t])根据格式指令将struct_time(或时间元组)格式化为字符串。如果不传第二个参数,将使用当前本地时间。这是Python中最灵活的时间格式化函数。
import time
# 最常见的格式
now = time.localtime()
formatted = time.strftime("%Y-%m-%d %H:%M:%S", now)
print(f"标准格式: {formatted}")
# 中文友好的格式
cn_format = time.strftime("%Y年%m月%d日 %H时%M分%S秒", now)
print(f"中文格式: {cn_format}")
# ISO 8601 格式
iso = time.strftime("%Y-%m-%dT%H:%M:%S%z", now)
print(f"ISO 8601: {iso}")
# 文件名安全格式
filename = time.strftime("backup_%Y%m%d_%H%M%S.db", now)
print(f"文件名 : {filename}")
# 日志格式
log_fmt = time.strftime("[%Y-%m-%d %H:%M:%S] [%(name)s] %(message)s")
# 注:此处的 %(name)s 为日志模块特有,演示 strftime 的灵活性
print(f"日志格式: {formatted}")
5.2 strftime格式指令大全
| 指令 | 含义 | 示例 |
| %Y | 四位年份 | 2026 |
| %y | 两位年份 | 26 |
| %m | 两位月份(01~12) | 05 |
| %d | 两位日期(01~31) | 05 |
| %H | 24小时制小时(00~23) | 14 |
| %I | 12小时制小时(01~12) | 02 |
| %M | 两位分钟(00~59) | 30 |
| %S | 两位秒(00~59) | 45 |
| %p | AM/PM 标记 | PM |
| %a | 缩写星期名 | Mon |
| %A | 完整星期名 | Monday |
| %b | 缩写月份名 | May |
| %B | 完整月份名 | May |
| %j | 年中第几天(001~366) | 125 |
| %w | 周中第几天(0=周日, 6=周六) | 2 |
| %U | 年中第几周(周日为一周开始) | 18 |
| %W | 年中第几周(周一为一周开始) | 18 |
| %z | 时区偏移(±HHMM) | +0800 |
| %Z | 时区名称 | CST |
| %% | 转义百分号 | % |
5.3 strptime() — 字符串解析为struct_time
time.strptime(string[, format])是strftime的逆操作——将遵循特定格式的时间字符串解析为struct_time。如果未指定格式,默认使用"%a %b %d %H:%M:%S %Y"格式(即asctime的输出格式)。
import time
# 最常见的用法
date_str = "2026-05-05 14:30:00"
parsed = time.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print(f"解析结果: {parsed}")
print(f"年份: {parsed.tm_year}, 月份: {parsed.tm_mon}, 日期: {parsed.tm_mday}")
# 中文格式解析
cn_str = "2026年05月05日 14时30分00秒"
try:
cn_parsed = time.strptime(cn_str, "%Y年%m月%d日 %H时%M分%S秒")
print(f"中文解析成功: {cn_parsed}")
except ValueError as e:
print(f"解析失败: {e}")
# ISO 8601 格式
iso_str = "2026-05-05T14:30:00"
iso_parsed = time.strptime(iso_str, "%Y-%m-%dT%H:%M:%S")
print(f"ISO 解析: {iso_parsed}")
# 解析后的 struct_time 可传给 mktime 转为时间戳
ts = time.mktime(iso_parsed)
print(f"对应时间戳: {ts}")
5.4 asctime() 与 ctime() — 简单格式
这两个函数提供了一种"快速且脏"的格式化方式:asctime(t)接收struct_time或时间元组,ctime(secs)接收时间戳。它们返回相同格式的固定宽度字符串(24字符)。
import time
# ctime: 时间戳 -> 简单字符串
now_ts = time.time()
print(f"ctime() : {time.ctime(now_ts)}")
# 输出: Tue May 5 14:30:00 2026
# asctime: struct_time -> 简单字符串
now_t = time.localtime()
print(f"asctime(): {time.asctime(now_t)}")
# 输出: Tue May 5 14:30:00 2026
# 不传参数时:asctime() = ctime() = "Tue May 5 14:30:00 2026"
print(f"asctime(): {time.asctime()}")
print(f"ctime() : {time.ctime()}")
# 注意:asctime 和 ctime 的格式固定,不可定制
# 等同于 strftime("%a %b %d %H:%M:%S %Y", t)
何时使用:ctime()和asctime()适用于快速调试输出、日志前缀等对格式要求不高的场景。对于需要精确控制格式的场景(如国际化、API响应),应使用strftime/strptime。
六、睡眠与计时
除了时间表示和转换功能,time模块还提供了程序执行控制(sleep)和性能测量(时钟函数)的能力。这部分功能在异步编程、定时任务和性能基准测试中有着广泛应用。
6.1 sleep() — 睡眠延迟
time.sleep(secs)使当前线程暂停执行指定的秒数(浮点数可实现亚秒级精度)。在调用期间,当前线程释放GIL(全局解释器锁),允许其他线程运行。这是一个系统调用,实际睡眠时间可能因系统负载和调度策略而略长于指定值。
import time
print("开始睡眠...")
time.sleep(1) # 睡眠 1 秒
print("1 秒后醒来")
time.sleep(0.5) # 睡眠 500 毫秒
print("500 毫秒后醒来")
time.sleep(0.001) # 睡眠 1 毫秒
print("1 毫秒后醒来")
# 实际睡眠时间可能有微小偏差
start = time.time()
time.sleep(1)
elapsed = time.time() - start
print(f"请求睡眠 1 秒,实际睡眠 {elapsed:.4f} 秒")
# 在循环中使用 sleep 实现定时任务
for i in range(3):
print(f"心跳 #{i + 1}")
time.sleep(0.5) # 每 500ms 打印一次
注意:sleep()会阻塞当前线程。在GUI应用和Web服务器的主线程中应避免长时间调用sleep(),否则会导致界面无响应或连接超时。在这些场景下应使用异步框架提供的定时器(如asyncio.sleep())。
6.2 多种时钟函数对比
Python 3.3+ 引入了PEP 418,新增了多个时钟函数以解决不同场景下的计时需求。理解它们之间的差异对于编写正确的性能测量代码至关重要。
| 函数 | 时间类型 | 精度 | 单调性 | 受系统时间调整影响 | 典型用途 |
| time() | 真实时间 | 微秒~纳秒 | 否 | 是 | 时间戳记录 |
| monotonic() | 单调时间 | 微秒~纳秒 | 是 | 否 | 经过时间测量 |
| perf_counter() | 高性能计数器 | 纳秒级 | 是 | 否 | 短时间间隔高精度测量 |
| process_time() | 进程CPU时间 | 微秒级 | 是 | 否 | CPU消耗分析 |
| thread_time() | 线程CPU时间 | 微秒级 | 是 | 否 | 线程CPU消耗分析 |
import time
# 演示不同时钟函数的差异
print(f"{'时钟':<15} {'值':<25} {'说明'}")
# time() - 真实时间(可能后退)
t1 = time.time()
time.sleep(0.1)
t2 = time.time()
print(f"{'time()':<15} {t2 - t1:<25.9f} {'受NTP和用户调整影响'}")
# monotonic() - 单调递增(始终向前)
m1 = time.monotonic()
time.sleep(0.1)
m2 = time.monotonic()
print(f"{'monotonic()':<15} {m2 - m1:<25.9f} {'不受系统时间调整影响'}")
# perf_counter() - 高性能计数器
p1 = time.perf_counter()
# 模拟一些计算密集型操作
sum(range(1_000_000))
p2 = time.perf_counter()
print(f"{'perf_counter()':<15} {p2 - p1:<25.9f} {'最高可用精度'}")
# process_time() - CPU时间(不包括 sleep)
cpu1 = time.process_time()
time.sleep(0.1) # sleep 不计入 CPU 时间
sum(range(1_000_000))
cpu2 = time.process_time()
print(f"{'process_time()':<15} {cpu2 - cpu1:<25.9f} {'仅包含CPU执行时间'}")
6.3 monotonic() — 单调时钟
单调时钟(monotonic clock)保证时间值始终向前递增,不会因为系统时间调整(如NTP同步、用户手动修改)而回退或跳跃。这是测量"经过了多少时间"的正确选择。
import time
# 单调时钟的正确用法:计算差值
start = time.monotonic()
# ... 执行需要计时的操作
time.sleep(2.5)
end = time.monotonic()
elapsed = end - start
print(f"经过时间: {elapsed:.2f} 秒")
# 注意:monotonic() 的绝对值没有意义,只有差值有用
# 它不代表任何现实世界的时间点
6.4 perf_counter() — 高性能计数器
time.perf_counter()提供了系统可用的最高精度计时器,适用于测量短时间间隔。它在许多系统中使用CPU的硬件性能计数器(如x86的TSC指令),精度可达纳秒级。Python 3.7+也提供了perf_counter_ns()返回纳秒整数。
import time
# 测量极短操作的性能
def measure_call(func, *args, **kwargs):
"""测量函数调用的耗时"""
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
return result, elapsed
# 测试列表推导式的性能
result, elapsed = measure_call(lambda: [x * x for x in range(10_000)])
print(f"列表推导式 10,000 次乘法: {elapsed:.6f} 秒")
# 使用 perf_counter_ns() 获得纳秒精度
start_ns = time.perf_counter_ns()
sum(range(1_000_000))
end_ns = time.perf_counter_ns()
print(f"纳秒级精度: {end_ns - start_ns} ns")
6.5 process_time() — 进程CPU时间
与perf_counter测量"墙上时间"不同,process_time()仅测量当前进程实际消耗的CPU时间。这意味着它不受sleep、I/O等待等非CPU操作的影响,适合分析代码的计算效率。
import time
# process_time 不受 sleep 影响
cpu_start = time.process_time()
time.sleep(1) # 这 1 秒不计入 CPU 时间
cpu_end = time.process_time()
print(f"包含 sleep 的 CPU 时间: {cpu_end - cpu_start:.6f} 秒 (应接近 0)")
# 纯计算操作会消耗 CPU 时间
cpu_start = time.process_time()
for _ in range(10_000_000):
pass
cpu_end = time.process_time()
print(f"10,000,000 次空循环 CPU 时间: {cpu_end - cpu_start:.6f} 秒")
七、实战案例
将上述知识点融会贯通,以下提供两个在实际开发中极为实用的案例。
7.1 案例一:代码执行时间测量(装饰器实现)
使用perf_counter和装饰器模式,实现一个可复用的函数执行时间测量工具。这个模式在性能调优、监控和调试中有着广泛应用。
import time
import functools
def timer(repetitions=1):
"""
函数执行时间测量装饰器
支持多次执行取平均值,减少单次测量的随机误差
"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# 预热:确保缓存和JIT已就绪
func(*args, **kwargs)
# 正式测量
total_time = 0.0
for i in range(repetitions):
start = time.perf_counter()
result = func(*args, **kwargs)
total_time += time.perf_counter() - start
avg_time = total_time / repetitions
print(f"[Timer] {func.__name__}: "
f"平均 {avg_time*1000:.4f} ms "
f"(共 {repetitions} 次)")
# 额外信息:CPU时间 vs 真实时间
cpu_start = time.process_time()
func(*args, **kwargs)
cpu_end = time.process_time()
cpu_time = cpu_end - cpu_start
print(f"[Timer] {func.__name__}: "
f"CPU时间 {cpu_time*1000:.4f} ms")
return result
return wrapper
return decorator
# 使用示例
@timer(repetitions=5)
def compute_squares(n):
"""计算前 n 个整数的平方和"""
return sum(i * i for i in range(n))
@timer(repetitions=3)
def sleep_demo(seconds):
"""演示 sleep 对 CPU 时间的影响"""
time.sleep(seconds)
return "done"
# 执行测试
result = compute_squares(1_000_000)
print(f"结果: {result}")
print("\n--- sleep 测试 ---")
result = sleep_demo(0.5)
print(f"结果: {result}")
7.2 案例二:定时器工具类
基于time.monotonic()实现一个简单的定时器类,支持启动、停止、重置和超时检查。这个模式的变体在游戏开发、网络编程(超时检测)和自动化测试中频繁出现。
import time
class Timer:
"""
基于单调时钟的定时器工具类
用于测量时间间隔和超时检测
"""
def __init__(self):
self._start = None
self._elapsed = 0.0
self._running = False
def start(self):
"""启动或重启定时器"""
self._start = time.monotonic()
self._elapsed = 0.0
self._running = True
return self
def stop(self):
"""停止定时器,返回经过时间"""
if self._running:
self._elapsed += time.monotonic() - self._start
self._running = False
return self._elapsed
def reset(self):
"""重置定时器"""
self._start = None
self._elapsed = 0.0
self._running = False
@property
def elapsed(self):
"""获取当前经过时间(不停止定时器)"""
if self._running:
return self._elapsed + (time.monotonic() - self._start)
return self._elapsed
def is_timeout(self, timeout):
"""检查是否超时"""
return self.elapsed >= timeout
def __enter__(self):
"""支持 with 语句"""
self.start()
return self
def __exit__(self, *args):
"""退出 with 语句时自动停止"""
self.stop()
def __str__(self):
"""友好字符串表示"""
return f"Timer(elapsed={self.elapsed:.3f}s, running={self._running})"
# 使用示例
print("=== Timer 基本用法 ===")
timer = Timer()
timer.start()
time.sleep(0.5)
print(f"经过时间: {timer.elapsed:.3f} 秒")
timer.stop()
print("\n=== 超时检测 ===")
timer.start()
for i in range(10):
time.sleep(0.1)
if timer.is_timeout(0.45):
print(f"超时!已过 {timer.elapsed:.2f} 秒,循环中止")
break
print(f"第 {i+1} 次心跳")
timer.stop()
print("\n=== with 语句用法 ===")
with Timer() as t:
time.sleep(0.3)
print(f"with 块耗时: {t.elapsed:.3f} 秒")
print("\n=== 测量代码块时间 ===")
with Timer() as t:
total = sum(i ** 0.5 for i in range(1_000_000))
print(f"计算平方根和: {t.elapsed:.4f} 秒")
7.3 综合应用:时间戳工具函数集
将本模块学到的所有知识整合为一个实用工具集。
import time
class TimeUtils:
"""时间处理工具集"""
@staticmethod
def now_ts():
"""获取当前秒级时间戳"""
return time.time()
@staticmethod
def now_ns():
"""获取当前纳秒级时间戳"""
return time.time_ns()
@staticmethod
def format_now(fmt="%Y-%m-%d %H:%M:%S"):
"""格式化当前时间"""
return time.strftime(fmt, time.localtime())
@staticmethod
def format_utc(fmt="%Y-%m-%d %H:%M:%S"):
"""格式化当前UTC时间"""
return time.strftime(fmt, time.gmtime())
@staticmethod
def parse_time(date_str, fmt="%Y-%m-%d %H:%M:%S"):
"""解析时间字符串为时间戳"""
struct_t = time.strptime(date_str, fmt)
return time.mktime(struct_t)
@staticmethod
def sleep_exact(seconds, tolerance=0.001):
"""
精确睡眠:通过忙等待补偿 sleep 的误差
适用于需要高精度延迟的场景
"""
start = time.perf_counter()
# 先粗略 sleep 大部分时间
if seconds > tolerance:
time.sleep(seconds - tolerance)
# 忙等待补偿剩余时间
while time.perf_counter() - start < seconds:
pass
@staticmethod
def benchmark(func, *args, repeat=5, **kwargs):
"""对函数进行基准测试"""
times = []
for _ in range(repeat):
start = time.perf_counter()
result = func(*args, **kwargs)
times.append(time.perf_counter() - start)
return {
"result": result,
"min": min(times),
"max": max(times),
"avg": sum(times) / len(times),
"total": sum(times),
}
# 使用示例
print(f"当前时间戳: {TimeUtils.now_ts()}")
print(f"格式化时间: {TimeUtils.format_now()}")
print(f"UTC时间: {TimeUtils.format_utc()}")
print(f"解析结果: {TimeUtils.parse_time('2026-05-05 10:00:00')}")
# 基准测试
result = TimeUtils.benchmark(sum, range(1_000_000), repeat=3)
print(f"基准测试: min={result['min']*1000:.2f}ms, "
f"avg={result['avg']*1000:.2f}ms, "
f"max={result['max']*1000:.2f}ms")
核心要点总结:
1. time()获取时间戳,time_ns()提供纳秒级精度(Python 3.7+)。
2. struct_time是9字段命名元组,作为时间戳和字符串的桥梁。
3. gmtime()转UTC,localtime()转本地时间,mktime()从本地时间转时间戳。
4. strftime/strptime是格式化和解析的主力,ctime/asctime用于快速输出。
5. 测量代码耗时应使用perf_counter()(高精度)或monotonic()(单调性),避免使用time()。
6. sleep()阻塞当前线程,非CPU操作不计入process_time()。