查看: 243|回复: 3

Python time模块核心函数用法与时间格式化实战

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
在Python日常开发中,时间处理是绕不开的基础操作。日志时间戳、接口耗时统计、定时任务调度、数据入库时间标记,都会用到时间相关功能。Python标准库中的time模块是解决这些问题的最轻量工具,它直接封装了系统底层时间接口,不需要安装第三方依赖。本文从实际开发角度梳理time模块的核心函数、时间格式转换流程以及典型的代码实践场景。

一、time模块能解决什么问题
time模块围绕Unix时间戳展开,核心能力包括:获取当前时间、在时间戳与结构化时间之间互转、格式化输出字符串时间、让程序暂停指定秒数、测量代码执行耗时。理解这些功能后,大多数基础时间需求都能直接覆盖。需要说明的是,time模块的时区处理能力有限,复杂的时区转换建议使用datetime模块配合pytz完成。

二、时间获取与结构化对象
time.time()返回自1970年1月1日00:00:00(UTC)以来的秒数,结果为浮点数。这是所有时间计算的基础值,适合用于记录事件发生顺序或计算时间差。
  1. import time
  2. timestamp = time.time()
  3. print(f"当前时间戳: {timestamp}")
  4. # 输出示例: 当前时间戳: 1745315368.123456
复制代码

time.localtime([secs])将时间戳转换为本地时区的结构化时间对象struct_time。不带参数时默认使用当前时间戳。struct_time是一个命名元组,可以直接访问tm_year、tm_mon、tm_mday等字段,在需要单独提取年、月、日、时、分、秒时非常方便。
  1. local_time = time.localtime()
  2. print(local_time)
  3. # 输出: 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)
  4. 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(星期缩写)。
  1. formatted = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
  2. print(formatted)
  3. # 输出: 2026-08-22 15:49:28
复制代码

反向操作是time.strptime(string[, format]),它把字符串按照指定格式解析为struct_time对象。解析时格式符必须与字符串严格匹配,否则会抛出ValueError。
  1. time_str = "2026-08-22 15:49:28"
  2. parsed_time = time.strptime(time_str, "%Y-%m-%d %H:%M:%S")
  3. print(parsed_time)
复制代码

四、时间戳与结构化时间双向转换
除了localtime和gmtime完成时间戳到struct_time的转换,time.mktime(t)则负责反向操作:传入本地时区的struct_time,返回对应的Unix时间戳。这个函数在读取配置文件中的时间字符串、转成时间戳做比较时比较实用。
  1. struct_time = time.localtime()
  2. timestamp_from_struct = time.mktime(struct_time)
  3. print(f"转换回的时间戳: {timestamp_from_struct}")
  4. new_struct = time.localtime(timestamp_from_struct)
  5. print(new_struct)
复制代码

五、程序休眠与性能计时
time.sleep(secs)使当前线程暂停执行指定秒数,参数可以是浮点数,例如0.5表示暂停500毫秒。注意该操作会阻塞当前线程,在GUI事件循环或asyncio异步任务中要避免直接调用,否则会卡住界面或阻塞事件循环。

性能计时要区分墙上时钟时间与CPU时间。time.perf_counter()返回高精度的性能计数器值,适合测量代码块的真实耗时,包括线程休眠、IO等待等所有时间。time.process_time()返回当前进程的系统和用户CPU时间总和,只统计进程占用的CPU时间,不受sleep和IO等待影响。
  1. start = time.perf_counter()
  2. time.sleep(0.1)
  3. end = time.perf_counter()
  4. print(f"操作耗时: {end - start:.6f} 秒")
  5. start_cpu = time.process_time()
  6. sum(range(1000000))
  7. end_cpu = time.process_time()
  8. 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以西为正。该值是只读属性,可用于判断当前时区的大致偏移量。
  1. readable = time.ctime()
  2. print(readable)
  3. # 输出: Fri Aug 22 15:49:28 2026
  4. asc_time = time.asctime(local_time)
  5. print(asc_time)
  6. # 输出: Fri Aug 22 15:49:28 2026
  7. print(f"本地时区偏移: {time.timezone} 秒")
复制代码

七、实战示例
下面是三个常见的开发场景,直接使用time模块即可完成。

计算函数执行时间:
  1. import time
  2. def expensive_function():
  3.     total = 0
  4.     for i in range(1000000):
  5.         total += i
  6.     return total
  7. start = time.perf_counter()
  8. result = expensive_function()
  9. end = time.perf_counter()
  10. print(f"函数结果: {result}")
  11. print(f"执行时间: {end - start:.4f} 秒")
复制代码

生成带时间戳的日志:
  1. def log_message(level, message):
  2.     timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
  3.     print(f"[{timestamp}] [{level}] {message}")
  4. log_message("INFO", "程序启动成功")
  5. time.sleep(1)
  6. log_message("WARNING", "磁盘空间不足")
复制代码

简单的倒计时:
  1. def countdown(seconds):
  2.     for i in range(seconds, 0, -1):
  3.         print(f"\r倒计时: {i} 秒", end="", flush=True)
  4.         time.sleep(1)
  5.     print("\r倒计时结束!")
  6. 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模块处理更复杂的时区运算和日期加减,就能在项目中构建完整的时间处理能力。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python time模块核心函数用法与时间格式化实战

干货满满,正好最近在写脚本要处理日志时间戳,这篇把time模块的常用函数和转换流程梳理得很清楚,尤其mktime和strptime的搭配以前总搞混,现在思路顺多了。期待楼主补全最后的实战代码示例。
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python time模块核心函数用法与时间格式化实战

感谢分享,写得很清晰!特别是 perf_counter 和 process_time 的对比,平时计时确实容易混淆。我一般处理日志时间戳就直接用 time.strftime,确实方便。 另外想问下,比如要解析带毫秒的时间字符串,time.strptime 是不是就不太支持?是不是得用 datetime 或者手动切分?
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python time模块核心函数用法与时间格式化实战

楼主的整理很清晰,把 time 模块的常用函数和转换关系都讲透了。平时写脚本确实经常跟这几个函数打交道,特别是 perf_counter 测耗时和 strftime/strptime 做格式化,基本是必用的。 有个小补充:做时间差计算时,如果跨天或者需要更精细的日期运算,直接拿时间戳相减再转成秒数也很方便,比如 `end - start` 得到浮点数后自己换算成时分秒。另外 `time.mktime` 处理本地时区时,如果机器时区设置不对,结果会偏差,这点跟楼主说的一致,复杂时区还是交给 datetime 更稳妥。 实战里的封装思路很实用,收藏了。期待楼主继续分享 datetime 模块的用法。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-8-23 18:22 , Processed in 0.026284 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部