![]()
11. struct_time 与转换函数
概述
struct_time是 time 模块中的时间元组类型,用于表示时间的各个组成部分。它是时间戳和字符串之间的桥梁,在底层时间操作中非常重要。
| 维度 | 内容 |
|---|
| What | 表示时间的元组结构,包含 9 个属性 |
| Why | 时间戳、字符串、datetime 之间的转换中介 |
| When | 底层时间操作、与 C 语言交互 |
| Where | time.gmtime(),time.localtime()返回 |
| Who | 需要底层时间操作的开发者 |
| How | t = time.localtime(); print(t.tm_year) |
1. struct_time 结构
1.1 属性详解
importtime# 获取当前时间的 struct_timet=time.localtime()# struct_time 包含 9 个属性print(f"tm_year:{t.tm_year}")# 年份,如 2026print(f"tm_mon:{t.tm_mon}")# 月份,1-12print(f"tm_mday:{t.tm_mday}")# 日期,1-31print(f"tm_hour:{t.tm_hour}")# 小时,0-23print(f"tm_min:{t.tm_min}")# 分钟,0-59print(f"tm_sec:{t.tm_sec}")# 秒,0-61(闰秒)print(f"tm_wday:{t.tm_wday}")# 星期,0=周一,6=周日print(f"tm_yday:{t.tm_yday}")# 年中的第几天,1-366print(f"tm_isdst:{t.tm_isdst}")# 夏令时,0=否,1=是,-1=未知
1.2 属性对照表
| 索引 | 属性 | 说明 | 范围 |
|---|
| 0 | tm_year | 年份 | 0000-9999 |
| 1 | tm_mon | 月份 | 1-12 |
| 2 | tm_mday | 日期 | 1-31 |
| 3 | tm_hour | 小时 | 0-23 |
| 4 | tm_min | 分钟 | 0-59 |
| 5 | tm_sec | 秒 | 0-61 |
| 6 | tm_wday | 星期 | 0-6(0=周一) |
| 7 | tm_yday | 年中的第几天 | 1-366 |
| 8 | tm_isdst | 夏令时 | 0, 1, -1 |
1.3 星期对照
importtime# 星期映射weekday_names=["周一","周二","周三","周四","周五","周六","周日"]t=time.localtime()print(f"今天是:{weekday_names[t.tm_wday]}")
2. 创建 struct_time
2.1 从当前时间创建
importtime# UTC 时间t_utc=time.gmtime()print(f"UTC:{t_utc}")# 本地时间t_local=time.localtime()print(f"本地:{t_local}")
2.2 从时间戳创建
importtime# 从时间戳创建timestamp=1745030000t1=time.gmtime(timestamp)# UTCt2=time.localtime(timestamp)# 本地print(f"时间戳:{timestamp}")print(f"UTC:{t1}")print(f"本地:{t2}")
2.3 从元组创建
importtime# 方式1:使用 time.struct_time 构造函数t=time.struct_time((2026,4,19,14,30,0,6,109,0))print(t)# 方式2:使用元组(需要 9 个元素)tuple_time=(2026,4,19,14,30,0,6,109,0)print(time.struct_time(tuple_time))
2.4 从字符串解析
importtime# strptime() 解析字符串date_str="2026-04-19 14:30:00"t=time.strptime(date_str,"%Y-%m-%d %H:%M:%S")print(f"解析结果:{t}")print(f"年份:{t.tm_year}")print(f"月份:{t.tm_mon}")
3. 转换函数
3.1 struct_time → 时间戳
importtime# mktime() 转换本地时间t_local=time.localtime()timestamp=time.mktime(t_local)print(f"struct_time → 时间戳:{timestamp}")# calendar.timegm() 转换 UTC 时间importcalendar t_utc=time.gmtime()utc_timestamp=calendar.timegm(t_utc)print(f"UTC struct_time → 时间戳:{utc_timestamp}")
3.2 struct_time → 字符串
importtime t=time.localtime()# asctime() - 固定格式print(time.asctime(t))# Sun Apr 19 14:30:00 2026# strftime() - 自定义格式print(time.strftime("%Y-%m-%d %H:%M:%S",t))print(time.strftime("%Y年%m月%d日",t))
3.3 字符串 → struct_time
importtime# strptime() - 解析字符串date_str="2026-04-19 14:30:00"t=time.strptime(date_str,"%Y-%m-%d %H:%M:%S")print(t)# 解析不同格式formats=[("2026-04-19","%Y-%m-%d"),("2026/04/19","%Y/%m/%d"),("2026年04月19日","%Y年%m月%d日"),("Apr 19, 2026","%b %d, %Y"),]fordate_str,fmtinformats:t=time.strptime(date_str,fmt)print(f"{date_str:20}→{t.tm_year}-{t.tm_mon}-{t.tm_mday}")
4. 实用示例
4.1 时间分量提取
importtimedefget_time_components(t=None):"""获取时间的各个分量"""iftisNone:t=time.localtime()return{"year":t.tm_year,"month":t.tm_mon,"day":t.tm_mday,"hour":t.tm_hour,"minute":t.tm_min,"second":t.tm_sec,"weekday":t.tm_wday,"yearday":t.tm_yday,"isdst":t.tm_isdst,}components=get_time_components()forkey,valueincomponents.items():print(f"{key}:{value}")
4.2 判断是否闰年
importtimedefis_leap_year(year):"""判断闰年"""returnyear%4==0and(year%100!=0oryear%400==0)t=time.localtime()print(f"{t.tm_year}年是闰年:{is_leap_year(t.tm_year)}")
4.3 获取月份天数
importtimeimportcalendardefget_month_days(year,month):"""获取月份天数"""returncalendar.monthrange(year,month)[1]t=time.localtime()print(f"{t.tm_year}年{t.tm_mon}月有{get_month_days(t.tm_year,t.tm_mon)}天")
4.4 计算两个日期之间的天数
importtimeimportcalendardefdays_between(date1_str,date2_str,fmt="%Y-%m-%d"):"""计算两个日期之间的天数"""t1=time.strptime(date1_str,fmt)t2=time.strptime(date2_str,fmt)timestamp1=time.mktime(t1)timestamp2=time.mktime(t2)returnabs(int((timestamp2-timestamp1)/86400))# 示例print(f"天数差:{days_between('2026-01-01','2026-12-31')}天")
5. 完整示例
importtimeprint("="*50)print("struct_time 综合示例")print("="*50)# 1. 获取 struct_timeprint("\n1. 获取 struct_time")utc_t=time.gmtime()local_t=time.localtime()print(f"UTC:{utc_t}")print(f"本地:{local_t}")# 2. 访问属性print("\n2. 访问属性")print(f"当前时间:{local_t.tm_year}-{local_t.tm_mon:02d}-{local_t.tm_mday:02d}")print(f"当前时间:{local_t.tm_hour:02d}:{local_t.tm_min:02d}:{local_t.tm_sec:02d}")# 3. 转换print("\n3. 转换")timestamp=time.mktime(local_t)print(f"时间戳:{timestamp}")# 4. 格式化print("\n4. 格式化")print(f"asctime:{time.asctime(local_t)}")print(f"strftime:{time.strftime('%Y-%m-%d %H:%M:%S',local_t)}")# 5. 解析print("\n5. 解析")date_str="2026-04-19 14:30:00"parsed=time.strptime(date_str,"%Y-%m-%d %H:%M:%S")print(f"解析 '{date_str}':{parsed}")
6. 常见陷阱
| 陷阱 | 说明 | 解决方案 |
|---|
| 星期起始 | tm_wday从 0(周一)开始 | 注意与datetime.weekday()一致 |
| 闰秒 | tm_sec范围 0-61 | 一般忽略 60-61 |
| 夏令时 | tm_isdst可能为 -1 | 使用zoneinfo处理 |
| 时区 | mktime()假设本地时区 | 使用calendar.timegm()处理 UTC |
7. 总结
| 操作 | 函数 | 方向 |
|---|
| 获取 UTC | gmtime() | 时间戳 → struct_time |
| 获取本地 | localtime() | 时间戳 → struct_time |
| 转时间戳 | mktime() | struct_time → 时间戳 |
| 转字符串 | asctime() | struct_time → 字符串 |
| 转字符串 | strftime() | struct_time → 字符串 |
| 解析字符串 | strptime() | 字符串 → struct_time |