@TOC
一、概述
time
模块提供了各种与时间相关的函数。相关功能还可以参阅datetime
和 calendar
模块。
尽管所有平台皆可引用此模块,但模块内的函数并不是所有平台都可用。此模块中定义的大多数函数的实现都是调用其所在平台的C语言库的同名函数。因为这些函数的语义可能因平台而异,所以使用时最好查阅对应平台的相关文档。
二、术语
下面是一些名词术语的解释
2.1 UTC
协调世界时(Coordinated Universal Time)的缩写。它以前也被称为格林威治标准时间(GMT)。使用UTC而不是CUT作为缩写是英语与法语(Temps Universel Coordonné)之间妥协的结果,不是什么低级错误。
2.2 DST
夏令时(Daylight Saving Time)的缩写,在一年的某一段时间中将当地时间调整(通常)一小时。 夏令时的规则非常神奇(由当地法律确定),并且每年的起止时间都不同。C语言库中有一个表格,记录了各地的夏令时规则(实际上,为了灵活性,C语言库通常是从某个系统文件中读取这张表)。从这个角度而言,这张表是夏令时规则的唯一权威真理。
2.3 epoch
起始的时间点,即 time.gmtime(0)
的返回值。 这在所有平台上都是 1970-01-01, 00:00:00 (UTC)。
2.4 纪元秒数
指自 epoch (纪元)时间点以来经过的总秒数,通常不包括[闰秒。 在所有符合 POSIX 标准的平台上,闰秒都不会记录在总秒数中。
三、惯例
下面是一些惯例的说明
3.1 有限的过去,有限的未来
此模块中只能处理有限的时间区间,可能无法处理 epoch 之前或遥远未来的日期和时间。 “遥远未来”的分界点是由 C 库确定的;对于 32 位系统,它通常是在 2038 年。
3.2 两位数年份,68大69小
函数 strptime()
在接收到 %y
格式代码时可以解析使用 2 位数表示的年份。当解析 2 位数年份时,函数会按照 POSIX 和 ISO C 标准进行年份转换:数值 69–99 被映射为 1969–1999;数值 0–68 被映射为 2000–2068。
3.3 Unix的老旧时钟
由于平台限制,各种实时函数的精度可能低于其值或参数所要求(或给定)的精度。例如,在大多数Unix系统上,时钟频率仅为每秒50或100次。
另一方面,time()
和 sleep()
的精度优于它们的 Unix 等价物:时间表示为浮点数,time()
返回可用的最准确时间,并且 sleep()
将接受带有非零小数部分的时间。
3.4 时间转换关系
时间值由gmtime()
,localtime()
和 strptime()
返回,并被asctime()
, mktime()
和 strftime()
接受,是一个 9 个整数的序列。gmtime()
, localtime()
和strptime()
的返回值还提供各个字段的属性名称。具体字段属性请看struct_time
章节。
使用以下函数在时间表示之间进行转换:
从 | 到 | 使用 |
---|---|---|
自纪元以来的秒数 | UTC 的 struct_time | gmtime() |
自纪元以来的秒数 | 本地时间的 struct_time | localtime() |
UTC 的 struct_time | 自纪元以来的秒数 | calendar.timegm() |
本地时间的 struct_time | 自纪元以来的秒数 | mktime() |
四、函数
4.8 time.process_time()
(以小数表示的秒为单位)返回当前进程的系统和用户 CPU 时间的总计值。 它不包括睡眠状态所消耗的时间。 根据定义它只作用于进程范围。 返回值的参考点未被定义,因此只有两次调用之间的差值才是有效的。
# 记录开始时间点
start_time = time.process_time()
# 进行一些计算或操作
for i in range(1000000):pass
# 记录结束时间点
end_time = time.process_time()
# 计算执行时间
elapsed_time = end_time - start_time
print(f"执行时间:0.0561 秒")# 执行结果
执行时间:0.03125 秒
4.9 time.sleep(secs)
调用方线程暂停执行给定的秒数。 该参数可以为浮点数以指定一个更精确的休眠时间。如果休眠被信号打断并且信号处理句柄未引发异常,休眠将基于重新计算的时延重新开始。暂停时间有可能比请求的要长出一段不确定的时间,因为会受系统中的其他活动排期影响。在 Windows 上,如果 secs 为零,线程会将其时间片的剩余部分让渡给任何其他准备要运行的线程。 如果没有准备要运行的其他线程,该函数将立即返回,而线程将继续执行。如果 secs 为零,则会使用 Sleep(0)
。
time.sleep(5)
print("5 秒已过")# 执行结果
5 秒已过
4.10 time.strftime(format[, t])
转换一个元组或struct_time
表示的由gmtime()
或 localtime()
返回的时间到由 format 参数指定的字符串。如果未提供 t ,则使用由 localtime()
返回的当前时间。 format 必须是一个字符串。如果 t 中的任何字段超出允许范围,则引发ValueError
。
0是时间元组中任何位置的合法参数;如果它通常是非法的,则该值被强制改为正确的值。
以下指令可以嵌入 format 字符串中:
指令 | 含意 | 备注 |
---|---|---|
%a | 本地化的缩写星期中每日的名称。 | |
%A | 本地化的星期中每日的完整名称。 | |
%b | 本地化的月缩写名称。 | |
%B | 本地化的月完整名称。 | |
%c | 本地化的适当日期和时间表示。 | |
%d | 十进制数 [01,31] 表示的月中日。 | |
%H | 十进制数 [00,23] 表示的小时(24小时制)。 | |
%I | 十进制数 [01,12] 表示的小时(12小时制)。 | |
%j | 十进制数 [001,366] 表示的年中日。 | |
%m | 十进制数 [01,12] 表示的月。 | |
%M | 十进制数 [00,59] 表示的分钟。 | |
%p | 本地化的 AM 或 PM 。 | (1) |
%S | 十进制数 [00,61] 表示的秒。 | (2) |
%U | 十进制数 [00,53] 表示的一年中的周数(星期日作为一周的第一天)。 在第一个星期日之前的新年中的所有日子都被认为是在第 0 周。 | (3) |
%w | 十进制数 [0(星期日),6] 表示的周中日。 | |
%W | 十进制数 [00,53] 表示的一年中的周数(星期一作为一周的第一天)。 在第一个星期一之前的新年中的所有日子被认为是在第 0 周。 | (3) |
%x | 本地化的适当日期表示。 | |
%X | 本地化的适当时间表示。 | |
%y | 十进制数 [00,99] 表示的没有世纪的年份。 | |
%Y | 十进制数表示的带世纪的年份。 | |
%z | 时区偏移以格式 +HHMM 或 -HHMM 形式的 UTC/GMT 的正或负时差指示,其中H表示十进制小时数字,M表示小数分钟数字 [-23:59, +23:59] 。 | |
%Z | 时区名称(如果不存在时区,则不包含字符)。已弃用。 | |
%% | 字面的 '%' 字符。 |
注释:
-
当与strptime函数一起使用时,如果使用
%I
指令来解析小时,%p
指令只影响输出小时字段。 -
范围真的是
0
到61
;值60
在表示leap seconds
的时间戳中有效,并且由于历史原因支持值61
。 -
当与strptime函数一起使用时,
%U
和%W
仅用于指定星期几和年份的计算。# 获取当前时间 current_time = time.time() # 使用 strftime 格式化时间一 formatted_time = time.strftime("%H:%M:%S", time.localtime(current_time)) print("当前时间(格式化时间一):", formatted_time) # 使用 strftime 格式化时间二 formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(current_time)) print("当前时间(格式化时间二):", formatted_time) # 使用 strftime 格式化短日期 formatted_date = time.strftime("%d/%m/%Y", time.localtime(current_time)) print("当前时间(格式化短日期):", formatted_time) # 使用 strftime 格式化长日期 formatted_date = time.strftime("%A, %d %B %Y", time.localtime(current_time)) print("当前时间(格式化长日期):", formatted_time) # 使用 strftime 格式化完整日期和时间 formatted_datetime = time.strftime("%A, %d %B %Y, %H:%M:%S", time.localtime(current_time)) print("当前时间(格式化完整日期和时间):", formatted_time)# 执行结果 当前时间(格式化时间一): 12:16:42 当前时间(格式化时间二): 2024-02-24 12:16:42 当前时间(格式化短日期): 2024-02-24 12:16:42 当前时间(格式化长日期): 2024-02-24 12:16:42 当前时间(格式化完整日期和时间): 2024-02-24 12:16:42
4.11 time.strptime(string[, format])
根据格式解析表示时间的字符串。 返回值为一个被gmtime()
或 localtime()
返回的struct_time
。
format 参数使用与strftime()
相同的指令。 它默认为匹配ctime()
所返回的格式 "%a %b %d %H:%M:%S %Y"
。 如果 string 不能根据 format 来解析,或者解析后它有多余的数据,则会引发ValueError
。 当无法推断出更准确的值时,用于填充任何缺失数据的默认值是 (1900, 1, 1, 0, 0, 0, 0, 1, -1)
。 string 和 format 都必须为字符串。
# 格式化字符串,用于表示日期和时间
date_format = "%Y-%m-%d %H:%M:%S"
# 要解析的日期和时间字符串
date_string = "2023-09-25 14:30:45"
# 使用 strptime 解析日期和时间字符串
parsed_time = time.strptime(date_string, date_format)
# 输出解析后的时间元组
print("解析后的时间元组:", parsed_time)# 执行结果
解析后的时间元组: time.struct_time(tm_year=2023, tm_mon=9, tm_mday=25, tm_hour=14, tm_min=30, tm_sec=45, tm_wday=0, tm_yday=268, tm_is夏令时=-1)
4.12 class time.struct_time
返回的时间值序列的类型为gmtime()
、 localtime()
和strptime。它是一个带有named tuple
接口的对象:可以通过索引和属性名访问值。 存在以下值:
索引 | 属性 | 值 |
---|---|---|
0 | tm_year | (例如,1993) |
1 | tm_mon | range [1, 12] |
2 | tm_day | range [1, 31] |
3 | tm_hour | range [0, 23] |
4 | tm_min | range [0, 59] |
5 | tm_sec | range [0, 61];参见strftime() 中的 注释 (2) |
6 | tm_wday | 取值范围 [0, 6];周一为 0 |
7 | tm_yday | range [1, 366] |
8 | tm_is夏令时 | 0, 1 或 -1;如下所示 |
N/A | tm_zone | 时区名称的缩写 |
N/A | tm_gmtoff | 以秒为单位的UTC以东偏离 |
请注意,与C结构不同,月份值是 [1,12] 的范围,而不是 [0,11] 。
在调用 mktime()
时,tm_is夏令时
可以在夏令时生效时设置为1,而在夏令时不生效时设置为0。 值-1表示这是未知的,并且通常会导致填写正确的状态。
当一个长度不正确的元组被传递给期望struct_time
的函数,或者具有错误类型的元素时,会引发TypeError
。
# 获取当前时间
current_time = time.localtime()
# 输出当前时间的 struct_time 对象
print("当前时间的 struct_time 对象:", current_time)
# 访问 struct_time 对象的各个元素
print("年:", current_time.tm_year)
print("月:", current_time.tm_mon)
print("日:", current_time.tm_mday)
print("小时:", current_time.tm_hour)
print("分钟:", current_time.tm_min)
print("秒:", current_time.tm_sec)
print("一周中的第几天(0 表示星期一):", current_time.tm_wday)
print("一年中的第几天:", current_time.tm_yday)
print("是否是夏令时:", current_time.tm_is夏令时)# 执行结果
当前时间的 struct_time 对象: time.struct_time(tm_year=2024, tm_mon=2, tm_mday=24, tm_hour=12, tm_min=27, tm_sec=18, tm_wday=5, tm_yday=55, tm_is夏令时=0)
年: 2024
月: 2
日: 24
小时: 12
分钟: 27
秒: 18
一周中的第几天(0 表示星期一): 5
一年中的第几天: 55
是否是夏令时: 0
4.13 time.time()
返回以浮点数表示的从epoch
开始的秒数形式的时间。 对leap seconds
的处理取决于具体平台。 在 Windows 和大多数 Unix 系统中,闰秒不会被计入从epoch
开始的秒数形式的时间中。 这通常被称为 Unix 时间
。
请注意,即使时间总是作为浮点数返回,但并非所有系统都提供高于1秒的精度。虽然此函数通常返回非递减值,但如果在两次调用之间设置了系统时钟,则它可以返回比先前调用更低的值。
# 获取当前时间戳(自1970年1月1日以来的秒数)
current_timestamp = time.time()
# 输出当前时间戳
print("当前时间戳:", current_timestamp)
# 将当前时间戳转换为日期和时间字符串
formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(current_timestamp))
# 输出格式化后的日期和时间字符串
print("格式化后的日期和时间字符串:", formatted_time)# 执行结果
当前时间戳: 1708749105.776935
格式化后的日期和时间字符串: 2024-02-24 12:31:45
五、时区常量
5.1 time.altzone
本地夏令时时区的偏移量,以UTC为单位的秒数,如果已定义。如果当地夏令时时区在UTC以东(如在西欧,包括英国),则是负数。 只有当 daylight
非零时才使用它。
# 获取当前时间戳(自1970年1月1日以来的秒数)
current_timestamp = time.time()
print("当前时间戳:", current_timestamp)
# 获取当前时区偏移量(以秒为单位)
timezone_offset = time.altzone
print("当前时区偏移量(以秒为单位):", timezone_offset)
# 获取当前时区偏移量(以小时为单位)
timezone_offset_hours = timezone_offset / 3600
print("当前时区偏移量(以小时为单位):", timezone_offset_hours)# 执行结果
当前时间戳: 1708749985.8680549
当前时区偏移量(以秒为单位): -32400
当前时区偏移量(以小时为单位): -9.0
5.2 time.daylight
如果启用了夏令时,则为非零。
# 获取当前是否启用了夏令时
is_夏令时_enabled = time.daylight
print("当前是否启用了夏令时:", is_夏令时_enabled)# 执行结果
当前是否启用了夏令时: 0
5.3 time.timezone
本地(非夏令时)时区的偏移量,UTC以西的秒数(西欧大部分地区为负,美国为正,英国为零)。
# 获取当前时区偏移量(以分钟为单位)
timezone_offset_minutes = time.timezone
print("当前时区偏移量(以分钟为单位):", timezone_offset_minutes)
# 获取当前时区偏移量(以小时为单位)
timezone_offset_hours = timezone_offset_minutes / 60
print("当前时区偏移量(以小时为单位):", timezone_offset_hours)# 执行结果
当前时区偏移量(以分钟为单位): -28800
当前时区偏移量(以小时为单位): -480.0
5.4 time.tzname
两个字符串的元组:第一个是本地非夏令时时区的名称,第二个是本地夏令时时区的名称。 如果未定义夏令时时区,则不应使用第二个字符串。
# 获取当前时区的名称
tzname = time.tzname
print("当前时区名称:", tzname)
tzname1, tzname2 = tzname[0].encode('latin-1').decode('gbk'), tzname[1].encode('latin-1').decode('gbk')
print('当前时区名称:({},{})'.format(tzname1, tzname2))# 执行结果
当前时区名称: ('Öйú±ê׼ʱ¼ä', 'ÖйúÏÄÁîʱ')
当前时区名称:(中国标准时间,中国夏令时)
六、相关模块
6.1 模块 datetime
更多面向对象的日期和时间接口,以及多种处理日期和时间的类
6.2 模块locale
国际化服务模块。 区域的设置会影响strftime()
和strptime
中许多格式说明符的解析。
模块calendar
一般日历相关功能模块。这个模块的 timegm()
是函数gmtime()
的反函数。
may the odds be ever in your favor ~