使用datetime.strptime解析含%p %Z的时间字符串触发ValueError如何解决
问题原因
%p标识的解析依赖系统的LC_TIMElocale配置,如果你的运行环境不是英文locale,默认无法识别AM/PM这类英文上午/下午标识。- 标准库
datetime的%Z格式符支持非常有限,仅能识别UTC、GMT以及当前系统本地时区的缩写,类似CDT这类第三方时区缩写因为存在全球歧义,默认无法被解析。
解决方案
方案1:使用第三方库python-dateutil(推荐)
无需手动拼接格式串,可自动识别绝大多数日期格式,还支持自定义时区缩写映射,是处理各类非标时间字符串的首选方案。
from dateutil import parser from dateutil.tz import gettz time_str = 'Thursday, September 9, 2021 at 11:50 AM CDT' # 自定义时区缩写映射,避免歧义 tzinfos = {"CDT": gettz("America/Chicago")} dt = parser.parse(time_str, tzinfos=tzinfos)
方案2:仅使用Python标准库
如果环境不允许安装第三方依赖,可以通过手动调整locale+拆分处理时区的方式实现:
import datetime import locale # Python 3.9及以上版本自带zoneinfo,更低版本可安装`backports.zoneinfo`兼容 from zoneinfo import ZoneInfo # 临时切换时间相关locale到英文,保证可以识别AM/PM # Windows系统locale名填写'en_US',类Unix系统填写'en_US.UTF-8' try: locale.setlocale(locale.LC_TIME, 'en_US.UTF-8') except: locale.setlocale(locale.LC_TIME, 'en_US') time_str = 'Thursday, September 9, 2021 at 11:50 AM CDT' # 拆分时间主体和时区部分 time_body, tz_abbr = time_str.rsplit(maxsplit=1) # 解析无时区的时间对象 naive_dt = datetime.datetime.strptime(time_body, '%A, %B %d, %Y at %I:%M %p') # 手动维护时区缩写映射表,可根据需求扩展 tz_mapping = { "CDT": ZoneInfo("America/Chicago"), "CST": ZoneInfo("America/Chicago"), "EST": ZoneInfo("America/New_York"), "EDT": ZoneInfo("America/New_York") } # 给时间对象绑定时区 aware_dt = naive_dt.replace(tzinfo=tz_mapping[tz_abbr])
注意事项
时区缩写本身存在全球歧义,比如CST同时可以指代中国标准时间、美国中部标准时间、古巴标准时间,因此不建议依赖自动识别,最好手动维护业务场景内用到的时区缩写映射表,避免解析出错。
内容的提问来源于stack exchange,提问作者cjwehr
相关产品推荐
相关产品推荐

