mktime() 是 Python time 模块中的一个重要函数,它的作用与 time.localtime() 相反,用于将一个时间元组转换为一个浮点数时间戳。

(图片来源网络,侵删)
函数定义
mktime() 的定义如下:
time.mktime(t)
参数说明
t: 这是一个时间元组,通常由time.localtime()生成,它是一个包含 9 个元素的元组,格式如下:
| 索引 | 属性 | 值范围 | 描述 |
|---|---|---|---|
| 0 | tm_year |
2025 | 4 位数年份 |
| 1 | tm_mon |
1-12 | 月份 (1 代表一月) |
| 2 | tm_mday |
1-31 | 日 (在当月内) |
| 3 | tm_hour |
0-23 | 小时 (24小时制) |
| 4 | tm_min |
0-59 | 分钟 |
| 5 | tm_sec |
0-61 | 秒 (60 和 61 用于闰秒) |
| 6 | tm_wday |
0-6 | 星期几 (0 代表星期一) |
| 7 | tm_yday |
1-366 | 一年中的第几天 (1 代表 1月1日) |
| 8 | tm_isdst |
-1, 0, 或 1 | 夏令时标志 -1: mktime() 自动判断0: 非夏令时 1: 夏令时 |
重要提示:
- 时间元组中的前6个元素(年、月、日、时、分、秒)是必需的。
- 后3个元素(星期、一年中第几天、夏令时)可以省略,如果省略,
mktime()会根据前6个元素自动计算它们的值。 - 如果提供的日期无效(2月30日),
mktime()会抛出OverflowError或ValueError。
返回值
- 一个浮点数,表示自 1970年1月1日 00:00:00 UTC(纪元,Epoch)以来经过的秒数。
- 这个时间戳是本地时间的时间戳。
mktime()内部会先将本地时间转换为 UTC 时间,然后再计算从纪元到该 UTC 时间的总秒数。
核心概念:mktime() 与 localtime() 的关系
mktime() 和 time.localtime() 是一对互逆的操作,可以看作是“编码”和“解码”的过程。
localtime(timestamp): 解码,将一个时间戳(UTC时间)转换为一个表示本地时间的时间元组。mktime(tuple): 编码,将一个表示本地时间的时间元组转换为一个时间戳(本质上是UTC时间戳)。
这个关系是理解 mktime() 的关键。

(图片来源网络,侵删)
代码示例
示例 1:基本用法
import time
# 1. 创建一个时间元组 (年, 月, 日, 时, 分, 秒)
# 代表 2025年10月27日 15:30:00 (本地时间)
time_tuple = (2025, 10, 27, 15, 30, 0, 0, 0, 0)
# 2. 使用 mktime() 将时间元组转换为时间戳
timestamp = time.mktime(time_tuple)
print(f"时间元组: {time_tuple}")
print(f"转换后的时间戳: {timestamp}")
# 3. 验证:使用 localtime() 将时间戳转换回时间元组,看是否一致
recovered_tuple = time.localtime(timestamp)
print(f"转换回的时间元组: {recovered_tuple}")
# 4. 将时间戳格式化为可读的字符串
readable_time = time.ctime(timestamp)
print(f"可读时间字符串: {readable_time}")
输出可能如下(具体时间戳值会因时区而异):
时间元组: (2025, 10, 27, 15, 30, 0, 0, 0, 0)
转换后的时间戳: 1698376200.0
转换回的时间元组: time.struct_time(tm_year=2025, tm_mon=10, tm_mday=27, tm_hour=15, tm_min=30, tm_sec=0, tm_wday=4, tm_yday=300, tm_isdst=0)
可读时间字符串: Fri Oct 27 15:30:00 2025
注意:tm_wday (星期四) 和 tm_yday (一年中第300天) 是自动计算出来的。
示例 2:自动计算缺失的元组元素
你可以只提供前6个元素,mktime() 会自动处理其余部分。
import time
# 只提供年、月、日、时、分、秒
time_tuple_short = (2025, 5, 21, 10, 0, 0)
timestamp_short = time.mktime(time_tuple_short)
print(f"简化的时间元组: {time_tuple_short}")
print(f"转换后的时间戳: {timestamp_short}")
# 查看自动计算出的完整元组
full_tuple = time.localtime(timestamp_short)
print(f"自动计算的完整元组: {full_tuple}")
输出:

(图片来源网络,侵删)
简化的时间元组: (2025, 5, 21, 10, 0, 0)
转换后的时间戳: 1716336000.0
自动计算的完整元组: time.struct_time(tm_year=2025, tm_mon=5, tm_mday=21, tm_hour=10, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=142, tm_isdst=-1)
可以看到,tm_wday (星期二), tm_yday (第142天) 和 tm_isdst (-1,表示自动判断夏令时) 都被正确填充了。
示例 3:处理无效日期
如果提供一个不存在的日期,mktime() 会报错。
import time
# 2月没有30日
invalid_time_tuple = (2025, 2, 30, 10, 0, 0)
try:
timestamp = time.mktime(invalid_time_tuple)
except (OverflowError, ValueError) as e:
print(f"错误: {e}")
输出:
错误: mktime argument out of range
与 calendar.timegm() 的区别
mktime() 和 calendar.timegm() 都可以将时间元组转换为时间戳,但它们有一个关键区别:
time.mktime(t): 假定输入的时间元组是本地时间,它会根据你系统的时区信息进行转换。calendar.timegm(t): 假定输入的时间元组是UTC时间,它不依赖任何时区信息,直接计算从纪元开始的秒数。
示例:
假设你的系统时区是 UTC+8(北京时间)。
import time
import calendar
# 这个时间元组代表 2025-10-27 07:30:00 UTC
# 在北京时间 (UTC+8) 下,这对应的是 2025-10-27 15:30:00
utc_tuple = (2025, 10, 27, 7, 30, 0, 0, 0, 0)
# 1. 使用 mktime() (假设为本地时间)
# 它会把 (2025, 10, 27, 7, 30, 0) 当作北京时间,然后转换为UTC时间戳
# 这会导致错误的时间戳
timestamp_mktime = time.mktime(utc_tuple)
print(f"time.mktime() 结果 (错误): {timestamp_mktime}") # 会得到一个错误的时间戳
# 2. 使用 timegm() (明确指定为UTC时间)
# 它会正确地将 (2025, 10, 27, 7, 30, 0) 当作UTC时间,并计算正确的时间戳
timestamp_timegm = calendar.timegm(utc_tuple)
print(f"calendar.timegm() 结果 (正确): {timestamp_timegm}")
# 3. 正确使用 mktime() 的方式
# 如果你想用 mktime() 处理 UTC 时间,需要先将其转换为本地时间元组
# 这很繁琐,不推荐
local_timestamp_for_utc = time.mktime(time.gmtime(calendar.timegm(utc_tuple)))
print(f"通过 gmtime() + mktime() 的结果 (正确但繁琐): {local_timestamp_for_utc}")
- 当你的时间元组代表本地时间时,使用
time.mktime()。 - 当你的时间元组代表UTC时间时,使用
calendar.timegm(),这样更清晰、更不容易出错。
| 特性 | 描述 |
|---|---|
| 功能 | 将本地时间元组转换为浮点数时间戳。 |
| 输入 | 一个9元组 (tm_year, tm_mon, ..., tm_isdst),前6个是必需的。 |
| 输出 | 一个浮点数,表示从纪元(1970-01-01 UTC)开始的秒数。 |
| 核心关系 | 是 time.localtime() 的逆函数。 |
| 时区处理 | 内部将输入的本地时间转换为UTC,再计算时间戳。 |
| 常见用途 | 将程序中构建的日期时间对象转换为可计算的数值。 与需要时间戳的API或系统进行交互。 |
| 注意事项 | 输入的是本地时间。 如果要处理UTC时间,优先使用 calendar.timegm()。 |
