如何用Python按优先级解析北欧格式日期(先DMY后YMD)
自定义日期解析方案(适配DMY/YMD优先级)
我之前处理过北欧发票的日期解析需求,刚好可以给你一个灵活的实现,完美匹配你要的优先级规则,还能轻松适配不同地区的顺序要求。
核心思路
- 忽略分隔符:不管日期用
-、/还是.分隔,先提取出所有数字段 - 优先级匹配:按照指定的顺序尝试解析(默认DMY优先,再YMD),解析失败就自动尝试下一种格式
- 灵活适配:通过参数可以快速切换优先级(比如瑞典需要YMD优先)
代码实现
import datetime import re def parse_custom_date(date_str, priority=['DMY', 'YMD']): # 提取日期中的所有数字部分,自动忽略各种分隔符 date_parts = re.findall(r'\d+', date_str) if len(date_parts) != 3: # 非三段式日期,直接返回None(可根据需求改成抛出异常) return None # 处理两位年份转四位,这里默认转成20xx,可根据需求调整逻辑 def normalize_year(year_str): if len(year_str) == 2: return f"20{year_str}" return year_str # 按优先级顺序尝试解析 for fmt in priority: try: if fmt == 'DMY': # 日-月-年格式:第一段是日,第二段是月,第三段是年 day = int(date_parts[0]) month = int(date_parts[1]) year = int(normalize_year(date_parts[2])) return datetime.datetime(year, month, day) elif fmt == 'YMD': # 年-月-日格式:第一段是年,第二段是月,第三段是日 year = int(normalize_year(date_parts[0])) month = int(date_parts[1]) day = int(date_parts[2]) return datetime.datetime(year, month, day) except ValueError: # 解析失败(比如日>31、月>12),跳过当前格式试下一个 continue # 所有优先级格式都解析失败,返回None return None
测试你的示例
# 测试DMY优先的情况(挪威、丹麦等) print(parse_custom_date("01-02-03")) # 输出: datetime.datetime(2003, 2, 1, 0, 0) print(parse_custom_date("2003-02-01")) # 输出: datetime.datetime(2003, 2, 1, 0, 0) # 支持其他分隔符 print(parse_custom_date("01/02/2003")) # 输出: datetime.datetime(2003, 2, 1, 0, 0) print(parse_custom_date("2003.02.01")) # 输出: datetime.datetime(2003, 2, 1, 0, 0) # 适配瑞典的YMD优先规则 print(parse_custom_date("01-02-03", priority=['YMD', 'DMY'])) # 输出: datetime.datetime(2001, 2, 3, 0, 0)
关键细节说明
- 分隔符兼容:正则
\d+会提取所有连续数字,不管中间是-、/、.还是其他非数字字符,自动适配各种分隔方式 - 容错处理:如果某段数字不符合日期规则(比如月份是13),会自动跳过当前格式,尝试下一个优先级的解析逻辑
- 年份适配:默认把两位年份转成
20xx,如果需要兼容更早的年份(比如99转成1999),可以修改normalize_year函数的逻辑:def normalize_year(year_str): if len(year_str) == 2: year = int(year_str) return f"19{year_str}" if year > 50 else f"20{year_str}" return year_str - 扩展空间:如果需要支持其他格式(比如MDY),只需要在
priority参数里添加,并在函数中增加对应的解析分支即可
内容的提问来源于stack exchange,提问作者elgehelge
相关产品推荐
相关产品推荐

