ISO 8601日期时间:应使用U+002D还是U+2010连字符?
ISO 8601日期格式的分隔符规范与兼容实践
问题场景
Python生成ISO-8601格式日期时,使用的是U+002D(普通减号):
>>> import datetime >>> datetime.datetime.now().isoformat(timespec='seconds') '2023-10-12T22:35:02'
用strptime解析这种标准格式完全正常:
>>> datetime.datetime.strptime('2023-10-12T22:35:02', '%Y-%m-%dT%H:%M:%S') datetime.datetime(2023, 10, 12, 22, 35, 2)
但如果外部来源的日期字符串用了U+2010(半角连字符),解析就会报错:
>>> datetime.datetime.strptime('2023‐10‐12T22:35:02', '%Y-%m-%dT%H:%M:%S') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_strptime.py", line 568, in _strptime_datetime tt, fraction, gmtoff_fraction = _strptime(data_string, format) File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_strptime.py", line 349, in _strptime raise ValueError("time data %r does not match format %r" % ValueError: time data '2023‐10‐12T22:35:02' does not match format '%Y-%m-%dT%H:%M:%S'
规范说明
ISO 8601标准明确规定,日期部分的分隔符必须使用U+002D(减号/连字符),U+2010属于排版用的半角连字符,并非标准要求的合法分隔符。Python的isoformat()方法生成的格式是完全符合标准的。
最佳实践建议
虽然标准只认U+002D,但实际业务中经常遇到外部数据源格式不规范的情况,做兼容处理是更稳妥的选择:
- 简单方案:解析前先把字符串中的U+2010替换成U+002D,再用标准格式解析:
date_str = '2023‐10‐12T22:35:02' normalized_str = date_str.replace('\u2010', '-') dt = datetime.datetime.strptime(normalized_str, '%Y-%m-%dT%H:%M:%S') - 更灵活的方案:使用
dateutil.parser模块(需先安装python-dateutil),它能自动识别多种非标准但常见的日期格式:from dateutil import parser dt = parser.parse('2023‐10‐12T22:35:02')
内容的提问来源于stack exchange,提问作者deadlock
相关产品推荐
相关产品推荐

