在Python日常开发中,时间处理是绕不开的基础操作。日志时间戳、接口耗时统计、定时任务调度、数据入库时间标记,都会用到时间相关功能。Python标准库中的time模块是解决这些问题的最轻量工具,它直接封装了系统底层时间接口,不需要安装第三方依赖。本文从实际开发角度梳理time模块的核心函数、时间格式转换流程以及典型的代码实践场景。
一、time模块能解决什么问题
time模块围绕Unix时间戳展开,核心能力包括:获取当前时间、在时间戳与结构化时间之间互转、格式化输出字符串时间、让程序暂停指定秒数、测量代码执行耗时。理解这些功能后,大多数基础时间需求都能直接覆盖。需要说明的是,time模块的时区处理能力有限,复杂的时区转换建议使用datetime模块配合pytz完成。
二、时间获取与结构化对象
time.time()返回自1970年1月1日00:00:00(UTC)以来的秒数,结果为浮点数。这是所有时间计算的基础值,适合用于记录事件发生顺序或计算时间差。
- import time
- timestamp = time.time()
- print(f"当前时间戳: {timestamp}")
- # 输出示例: 当前时间戳: 1745315368.123456
复制代码
time.localtime([secs])将时间戳转换为本地时区的结构化时间对象struct_time。不带参数时默认使用当前时间戳。struct_time是一个命名元组,可以直接访问tm_year、tm_mon、tm_mday等字段,在需要单独提取年、月、日、时、分、秒时非常方便。
- local_time = time.localtime()
- print(local_time)
- # 输出: time.struct_time(tm_year=2026, tm_mon=8, tm_mday=22, tm_hour=15, tm_min=49, tm_sec=28, tm_wday=4, tm_yday=234, tm_isdst=0)
- print(f"年份: {local_time.tm_year} 月份: {local_time.tm_mon} 日期: {local_time.tm_mday}")
复制代码
time.gmtime([secs])用法与localtime相同,区别在于它转换的是UTC标准时间,而不是本地时间。在需要统一时间基准、跨时区日志记录或国际协作场景下,gmtime能避免本地时区差异造成的混乱。
三、时间格式化与解析
将struct_time转换为字符串,使用time.strftime(format[, t])。格式化字符串由多个占位符组成,常用的有:%Y(四位年份)、%m(月份01-12)、%d(日期01-31)、%H(小时00-23)、%M(分钟00-59)、%S(秒00-59)、%A(星期全名)、%a(星期缩写)。
- formatted = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
- print(formatted)
- # 输出: 2026-08-22 15:49:28
复制代码
反向操作是time.strptime(string[, format]),它把字符串按照指定格式解析为struct_time对象。解析时格式符必须与字符串严格匹配,否则会抛出ValueError。
- time_str = "2026-08-22 15:49:28"
- parsed_time = time.strptime(time_str, "%Y-%m-%d %H:%M:%S")
- print(parsed_time)
复制代码
四、时间戳与结构化时间双向转换
除了localtime和gmtime完成时间戳到struct_time的转换,time.mktime(t)则负责反向操作:传入本地时区的struct_time,返回对应的Unix时间戳。这个函数在读取配置文件中的时间字符串、转成时间戳做比较时比较实用。
- struct_time = time.localtime()
- timestamp_from_struct = time.mktime(struct_time)
- print(f"转换回的时间戳: {timestamp_from_struct}")
- new_struct = time.localtime(timestamp_from_struct)
- print(new_struct)
复制代码
五、程序休眠与性能计时
time.sleep(secs)使当前线程暂停执行指定秒数,参数可以是浮点数,例如0.5表示暂停500毫秒。注意该操作会阻塞当前线程,在GUI事件循环或asyncio异步任务中要避免直接调用,否则会卡住界面或阻塞事件循环。
性能计时要区分墙上时钟时间与CPU时间。time.perf_counter()返回高精度的性能计数器值,适合测量代码块的真实耗时,包括线程休眠、IO等待等所有时间。time.process_time()返回当前进程的系统和用户CPU时间总和,只统计进程占用的CPU时间,不受sleep和IO等待影响。
- start = time.perf_counter()
- time.sleep(0.1)
- end = time.perf_counter()
- print(f"操作耗时: {end - start:.6f} 秒")
- start_cpu = time.process_time()
- sum(range(1000000))
- end_cpu = time.process_time()
- print(f"CPU 时间: {end_cpu - start_cpu:.6f} 秒")
复制代码
六、其他实用函数
time.ctime([secs])将时间戳转换为类似"Fri Aug 22 15:49:28 2026"的可读字符串,不带参数时使用当前时间。time.asctime([t])接受struct_time对象作为参数,输出格式与ctime完全一致。二者区别只在于入参类型。time.timezone返回本地时区相对于UTC的偏移秒数,UTC以西为正。该值是只读属性,可用于判断当前时区的大致偏移量。
- readable = time.ctime()
- print(readable)
- # 输出: Fri Aug 22 15:49:28 2026
- asc_time = time.asctime(local_time)
- print(asc_time)
- # 输出: Fri Aug 22 15:49:28 2026
- print(f"本地时区偏移: {time.timezone} 秒")
复制代码
七、实战示例
下面是三个常见的开发场景,直接使用time模块即可完成。
计算函数执行时间:
- import time
- def expensive_function():
- total = 0
- for i in range(1000000):
- total += i
- return total
- start = time.perf_counter()
- result = expensive_function()
- end = time.perf_counter()
- print(f"函数结果: {result}")
- print(f"执行时间: {end - start:.4f} 秒")
复制代码
生成带时间戳的日志:
- def log_message(level, message):
- timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
- print(f"[{timestamp}] [{level}] {message}")
- log_message("INFO", "程序启动成功")
- time.sleep(1)
- log_message("WARNING", "磁盘空间不足")
复制代码
简单的倒计时:
- def countdown(seconds):
- for i in range(seconds, 0, -1):
- print(f"\r倒计时: {i} 秒", end="", flush=True)
- time.sleep(1)
- print("\r倒计时结束!")
- countdown(5)
复制代码
八、注意事项归纳
在项目中使用time模块时,以下几点值得留意。
第一,time.time()返回的浮点数精度受操作系统影响,通常能达到微秒级,但不适合直接做高精度性能对比,性能分析应优先使用time.perf_counter()。
第二,strftime与strptime的格式字符串是严格的,格式符数量和类型不匹配会直接报错,建议在公共工具函数中封装统一的格式化模板。
第三,time.sleep()是阻塞调用,会挂起当前线程。多线程场景下可以用threading.Event.wait()实现可中断的等待,异步编程中则应该改用asyncio.sleep()。
第四,测量耗时需求的不同决定了函数选择:需要用户感知的真实流逝时间用perf_counter,需要评估代码本身对CPU的占用用process_time。
第五,time模块的时区处理只支持查看系统当前时区,无法直接进行时区转换。涉及跨时区业务时,应该由datetime模块的timezone类或pytz库接管。
总体来看,time模块是Python时间处理的基石。time.time()、time.localtime()、time.strftime()、time.sleep()、time.perf_counter()这五个函数覆盖了绝大多数日常场景。结合datetime模块处理更复杂的时区运算和日期加减,就能在项目中构建完整的时间处理能力。 |