为何使用%m%d%Y解析mmddyy格式日期未触发验证失败?
为什么strptime用%m%d%Y解析6位mmddyy字符串未报错?
我想用strptime()创建datetime对象来验证字符串格式,预期格式是mmddyy(比如112023)。用格式码%m%d%y解析时结果符合预期:
file_name_date = "112023" print(bool(datetime.strptime(file_name_date, "%m%d%y"))) print(datetime.strptime(file_name_date, "%m%d%y"))
输出:
True 2023-11-20 00:00:00
但用格式码%m%d%Y时居然也能运行——我本以为它要求4位年份会验证失败,结果却解析出2023-01-01:
file_name_date = "112023" print(bool(datetime.strptime(file_name_date, "%m%d%Y"))) print(datetime.strptime(file_name_date, "%m%d%Y"))
输出:
True 2023-01-01 00:00:00
请问这是什么原因?
原因解析
Python的datetime.strptime()不会严格校验输入字符串的总长度与格式码要求的长度完全匹配,也不会强制%Y必须对应4位数字,它的解析逻辑是:
- 按格式码顺序,从左到右读取连续的数字字符匹配每个格式码
- 当剩余字符不足以满足格式码的“预期长度”时,仍会尝试解析该格式码
- 若解析后仍有日期部分(月、日)未被匹配到,会自动用默认值
1填充
针对你的例子的具体逻辑
你输入的"112023"是6位字符串,而%m%d%Y的预期是2位月+2位日+4位年(共8位),长度不匹配的情况下:
%m读取前两位"11"作为月份%d读取接下来两位"20"作为日期- 剩余两位
"23"被传给%Y,%Y会直接将其解析为公元23年(而非2023年)
你得到的2023-01-01大概率是测试时的笔误,实际运行应该输出0023-11-20 00:00:00。如果确实得到2023-01-01,则可能是格式码或输入字符串写错了(比如误将格式码写成%Y%m%d,此时"112023"会被解析为年份1120,无效月份23触发默认值1,无剩余字符填充日期为1)。
如何严格验证格式
strptime()本身不做严格的格式校验,如果你需要确保输入是标准的6位mmddyy格式,需要额外做校验:
- 先检查字符串长度是否为6位
- 用正则表达式验证是否为纯数字
- 再用
%m%d%y解析并捕获可能的日期有效性错误(比如月份>12、日期超过当月天数)
示例代码:
import re from datetime import datetime file_name_date = "112023" # 先验证格式合法性 if re.fullmatch(r'\d{6}', file_name_date): try: dt = datetime.strptime(file_name_date, "%m%d%y") print("解析成功:", dt) except ValueError: print("日期无效(如月份或日期超出范围)") else: print("输入格式错误,必须是6位数字的mmddyy格式")
内容的提问来源于stack exchange,提问作者iambdot
相关产品推荐
相关产品推荐

