如何灵活解析含可选时分秒的PT格式时间字符串为datetime.time?
通用解析PT格式时间字符串为datetime.time的方案
针对解析含可选时、分、秒的PT格式时间字符串(如PT1H28M26S、PT3H8M、PT4M)到datetime.time的需求,以下提供两种通用方案,无需冗余的条件判断:
方案一:自定义正则解析(无第三方依赖)
通过正则匹配每个可选的时间部分,对未捕获到的字段默认设为0,完美兼容所有格式:
import re from datetime import time def parse_pt_time(pt_str): # 匹配PT后可选的时、分、秒部分,每个部分独立可选 pattern = r'PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?' match = re.fullmatch(pattern, pt_str) if not match: raise ValueError(f"无效的PT时间格式: {pt_str}") # 提取各部分数值,不存在则设为0 hours = int(match.group(1)) if match.group(1) else 0 minutes = int(match.group(2)) if match.group(2) else 0 seconds = int(match.group(3)) if match.group(3) else 0 return time(hours, minutes, seconds) # 测试示例 print(parse_pt_time('PT1H28M26S')) # 输出: 01:28:26 print(parse_pt_time('PT5H23M26S')) # 输出: 05:23:26 print(parse_pt_time('PT3H8M')) # 输出: 03:08:00 print(parse_pt_time('PT4M')) # 输出: 00:04:00
原理说明
正则表达式中,(?:(\d+)H)?表示可选的小时部分:
(?:...)是非捕获组,仅用于分组不捕获整体(\d+)H捕获数字加H的小时值- 末尾的
?表示该部分可缺失
同理处理分、秒部分,确保即使某个字段不存在,正则仍能匹配成功,仅对应分组为None,后续通过判断转为0即可。
方案二:借助第三方库isodate(简洁高效)
PT格式属于ISO 8601时长规范,isodate库可直接解析这类字符串,再转换为datetime.time:
from isodate import parse_duration from datetime import time def parse_pt_time(pt_str): # 解析为timedelta对象 duration = parse_duration(pt_str) total_seconds = duration.total_seconds() # 计算时、分、秒 hours = int(total_seconds // 3600) remaining_seconds = total_seconds % 3600 minutes = int(remaining_seconds // 60) seconds = int(remaining_seconds % 60) return time(hours, minutes, seconds)
使用前需安装依赖:
pip install isodate
优势
该方案无需自己编写正则,还能支持带小数的时长(如PT1.5H、PT30.5S),适用性更广。
为什么现有方案失效?
- 旧正则方案:要求时、分、秒三个字段必须同时存在,缺失任意一个都会导致匹配失败(
match为None),进而调用groups()时报错。 strptime方案:格式字符串是固定模板,必须与输入字符串完全匹配,缺失部分会直接解析失败。
内容的提问来源于stack exchange,提问作者Ahek
相关产品推荐
相关产品推荐

