一文读懂 Python 的 time 模块:时间处理全攻略
在 Python 编程中,对时间的处理是一项常见且重要的任务。time
模块作为 Python 标准库的一部分,提供了丰富的函数和工具,用于访问、转换和操作时间。本文将深入剖析time
模块的各个方面,包括基本概念、常用函数、时间表示的转换、时钟类型、时区处理以及相关注意事项,帮助读者全面掌握time
模块的使用,提升在时间处理相关编程场景中的能力。
文章目录
一、time 模块基础概念
(一)epoch 与纪元秒数
epoch 是时间起始点,在所有平台上,time.gmtime(0)
的返回值都是 1970-01-01 00:00:00 (UTC)。纪元秒数指从 epoch 开始经过的总秒数,通常不包含闰秒,在符合 POSIX 标准的平台上,闰秒不会被记录在总秒数中。
(二)时间表示与术语
- UTC 与 DST:UTC 即协调世界时,曾被称为格林威治标准时间(GMT)。DST 是夏令时,在一年中特定时段将当地时间调整(通常为一小时),其规则由当地法律确定,C 语言库通过表格(通常从系统文件读取)记录各地规则 。
- struct_time 对象:
gmtime()
、localtime()
和strptime()
返回的时间值是一个包含 9 个整数的序列,以struct_time
对象表示。该对象可通过索引和属性名访问各个时间字段,如tm_year
(年份)、tm_mon
(月份,范围是 [1, 12])等。
二、time 模块的常用函数
(一)时间转换函数
gmtime([secs])
:将自 epoch 开始的秒数转换为 UTC 时间的struct_time
对象,若未传入secs
,则使用当前时间。例如:
import time
utc_time = time.gmtime()
print(utc_time)
localtime([secs])
:与gmtime()
类似,但转换为本地时间。当 DST 适用于给定时间时,dst
标志设置为 1。若时间戳超出平台 C 函数支持范围,可能引发OverflowError
或OSError
。示例:
local_time = time.localtime()
print(local_time)
mktime(t)
:localtime()
的反函数,将struct_time
对象或 9 元组(需包含dst
标志,未知时用 - 1)表示的本地时间转换为自 epoch 开始的秒数(浮点数)。若输入值无效,会引发OverflowError
或ValueError
。例如:
time_tuple = (2024, 10, 1, 12, 0, 0, 0, 0, -1)
seconds = time.mktime(time_tuple)
print(seconds)
asctime([t])
:将gmtime()
或localtime()
返回的struct_time
对象或相应元组转换为指定格式的字符串,如 ‘Sun Jun 20 23:21:05 1993’。若未提供t
,则使用当前本地时间,且该函数不添加尾随换行符。示例:
time_str = time.asctime()
print(time_str)
ctime([secs])
:将距离 epoch 的秒数表示的时间转换为本地时间的字符串形式,等价于asctime(localtime(secs))
。若未提供secs
,则使用当前时间。示例:
ctime_str = time.ctime()
print(ctime_str)
函数名 | 作用 | 输入 | 输出 | 注意事项 |
---|---|---|---|---|
gmtime([secs]) | 将秒数转换为 UTC 时间的struct_time 对象 | 秒数(可选,默认当前时间) | struct_time 对象 | 忽略一秒以内的小数 |
localtime([secs]) | 将秒数转换为本地时间的struct_time 对象 | 秒数(可选,默认当前时间) | struct_time 对象 | 可能引发OverflowError 或OSError |
mktime(t) | 将struct_time 对象或 9 元组转换为秒数 | struct_time 对象或 9 元组 | 浮点数 | 输入无效时引发异常 |
asctime([t]) | 将struct_time 对象或元组转换为指定格式字符串 | struct_time 对象或元组(可选,默认当前本地时间) | 字符串 | 不添加尾随换行符 |
ctime([secs]) | 将秒数转换为本地时间的字符串形式 | 秒数(可选,默认当前时间) | 字符串 | 等价于asctime(localtime(secs)) |
(二)时间格式化函数
strftime(format [, t])
:根据指定的format
字符串,将gmtime()
或localtime()
返回的时间(struct_time
对象或元组)转换为字符串。format
字符串中包含各种指令,用于指定输出格式。例如:
current_time = time.localtime()
formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", current_time)
print(formatted_time)
strptime(string [, format])
:根据format
字符串解析表示时间的字符串,返回struct_time
对象。format
默认为匹配ctime()
返回的格式。若字符串无法解析或有多余数据,会引发ValueError
。示例:
time_str = "2024-10-01 12:00:00"
parsed_time = time.strptime(time_str, "%Y-%m-%d %H:%M:%S")
print(parsed_time)
(三)其他实用函数
time()
:返回以浮点数表示的从 epoch 开始的秒数,即 Unix 时间。不同平台对闰秒的处理方式不同,且部分系统精度可能低于 1 秒,系统时钟设置可能导致返回值出现异常。示例:
seconds_since_epoch = time.time()
print(seconds_since_epoch)
sleep(secs)
:使调用方线程暂停执行指定的秒数,secs
可以是浮点数以指定更精确的休眠时间。在 Windows 和 Unix 系统上的实现方式有所不同,且睡眠过程可能受信号中断和系统活动影响。例如:
print("开始睡眠")
time.sleep(2)
print("睡眠结束")
tzset()
:重置库例程使用的时间转换规则,通过设置环境变量TZ
来指定转换方式。该函数还会设置tzname
、timezone
、altzone
和daylight
等变量 。示例:
import os
os.environ['TZ'] = 'EST+05EDT,M4.1.0,M10.5.0'
time.tzset()
三、时钟类型与相关函数
(一)单调时钟
monotonic()
:返回一个单调时钟的值,该时钟不能倒退且不受系统时钟更新影响,只有两次调用之间的差值有效。可使用monotonic_ns()
避免float
类型导致的精度损失。示例:
start = time.monotonic()
# 执行一些操作
end = time.monotonic()
duration = end - start
print(f"操作耗时: {duration} 秒")
monotonic_ns()
:与monotonic()
类似,但返回时间为纳秒数。
(二)性能计数器
perf_counter()
:返回用于测量较短持续时间的高性能计数器的值,包括睡眠状态消耗的时间,作用于全系统范围,两次调用差值有效。可使用perf_counter_ns()
避免精度损失。例如:
start = time.perf_counter()
# 执行一些操作
end = time.perf_counter()
duration = end - start
print(f"操作耗时: {duration} 秒")
perf_counter_ns()
:返回纳秒时间。
(三)进程和线程时间
process_time()
:返回当前进程的系统和用户 CPU 时间总计值,不包括睡眠状态消耗时间,仅作用于进程范围,两次调用差值有效。可使用process_time_ns()
避免精度损失。示例:
start = time.process_time()
# 执行一些进程相关操作
end = time.process_time()
duration = end - start
print(f"进程操作耗时: {duration} 秒")
process_time_ns()
:返回纳秒时间。thread_time()
:返回当前线程的系统和用户 CPU 时间总计值,不包括睡眠状态消耗时间,仅作用于线程范围,可使用thread_time_ns()
避免精度损失。示例:
import threading
def thread_function():
start = time.thread_time()
# 线程执行一些操作
end = time.thread_time()
duration = end - start
print(f"线程操作耗时: {duration} 秒")
thread = threading.Thread(target=thread_function)
thread.start()
thread.join()
thread_time_ns()
:返回纳秒时间。
时钟类型 | 函数名 | 作用 | 精度 | 适用场景 |
---|---|---|---|---|
单调时钟 | monotonic() | 返回单调时钟值(秒) | 秒(float 类型,可通过monotonic_ns() 提高精度) | 测量相对时间间隔,不受系统时钟调整影响 |
monotonic_ns() | 返回单调时钟值(纳秒) | 纳秒 | 高精度测量相对时间间隔 | |
性能计数器 | perf_counter() | 返回高性能计数器值(秒),包含睡眠时间 | 秒(float 类型,可通过perf_counter_ns() 提高精度) | 精确测量短时间操作的耗时 |
perf_counter_ns() | 返回高性能计数器值(纳秒) | 纳秒 | 高精度测量短时间操作的耗时 | |
进程时间 | process_time() | 返回当前进程 CPU 时间总计值(秒),不包含睡眠时间 | 秒(float 类型,可通过process_time_ns() 提高精度) | 测量进程 CPU 使用时间 |
process_time_ns() | 返回当前进程 CPU 时间总计值(纳秒) | 纳秒 | 高精度测量进程 CPU 使用时间 | |
线程时间 | thread_time() | 返回当前线程 CPU 时间总计值(秒),不包含睡眠时间 | 秒(float 类型,可通过thread_time_ns() 提高精度) | 测量线程 CPU 使用时间 |
thread_time_ns() | 返回当前线程 CPU 时间总计值(纳秒) | 纳秒 | 高精度测量线程 CPU 使用时间 |
四、时区处理
(一)时区常量
time
模块提供了altzone
、daylight
、timezone
和tzname
等常量用于处理时区相关信息。但这些常量的值由模块加载或tzset()
最后一次调用时生效的时区规则确定,对于过去时间可能不准确,建议使用localtime()
结果中的tm_gmtoff
和tm_zone
获取时区信息。
(二)设置时区
通过设置环境变量TZ
并调用tzset()
函数,可以重置时间转换规则。TZ
环境变量有特定的格式,不同系统还可通过设置TZ
为系统 ‘zoneinfo’ 时区数据库路径来指定时区规则 。
五、注意事项与局限性
- 平台差异:
time
模块的函数在不同平台上的行为和可用性可能不同,部分函数仅在特定操作系统上可用,使用时需查阅对应平台文档。 - 精度问题:受系统限制,部分函数的精度可能无法达到预期,如在某些 Unix 系统上,时钟频率较低。使用
time()
和sleep()
时,虽然它们在 Python 中精度有所提升,但仍可能受系统活动影响。 - 时间范围限制:模块中的函数可能无法处理 epoch 之前或遥远未来的日期和时间,对于 32 位系统,“遥远未来” 通常指 2038 年之后。
总结
time
模块是 Python 处理时间的重要工具,涵盖了时间获取、转换、格式化以及时钟测量等多种功能。通过理解 epoch、UTC、DST 等基本概念,掌握常用函数的使用方法,以及注意不同时钟类型的特点和时区处理方式,开发者能够在编程中灵活处理各种时间相关需求。但在使用过程中,要充分考虑平台差异、精度问题和时间范围限制,确保程序的正确性和稳定性。
TAG:Python、time 模块、时间处理、时间转换、时区、时钟类型
相关学习资源
- Python 官方文档(https://docs.python.org/zh-cn/3.12/library/time.html):提供了
time
模块最权威和详细的说明,包括函数定义、参数、返回值以及示例代码等,是深入学习time
模块的基础资源。 - Tekin的Python编程秘籍库: Python 实用知识与技巧分享,涵盖基础、爬虫、数据分析等干货 本 Python 专栏聚焦实用知识,深入剖析基础语法、数据结构。分享爬虫、数据分析等热门领域实战技巧,辅以代码示例。无论新手入门还是进阶提升,都能在此收获满满干货,快速掌握 Python 编程精髓。