Python datetime %b解析异常:调用plt.figure()后日期解析失败
问题
在Anaconda Python 3.8.13环境中运行以下脚本:
import matplotlib.pyplot as plt import datetime as dt date = dt.datetime.strptime('02-Jan-2008 10:09:00', '%d-%b-%Y %H:%M:%S') print(date) fig = plt.figure() date2 = dt.datetime.strptime('02-Jan-2008 10:09:00', '%d-%b-%Y %H:%M:%S') print(date2)
首次执行dt.datetime.strptime成功输出2008-01-02 10:09:00,但调用plt.figure()后,相同的解析代码抛出如下错误:
Traceback (most recent call last):
File "./prova.py", line 17, in
date2 = dt.datetime.strptime('02-Jan-2008 10:09:00', '%d-%b-%Y %H:%M:%S')
File "/home/grieco/anaconda3/lib/python3.8/_strptime.py", line 568, in _strptime_datette
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/home/grieco/anaconda3/lib/python3.8/_strptime.py", line 349, in _strptime
raise ValueError("time data %r does not match format %r" %
ValueError: time data '02-Jan-2008 10:09:00' does not match format '%d-%b-%Y %H:%M:%S'
经排查,调用plt.figure()后日期解析语言切换为系统默认的西班牙语,即使关闭图形问题仍存在,需解决该问题使两次解析均成功输出日期。
解决方法
方法1:解析日期时强制指定英文区域设置
通过locale模块在解析前切换回英文区域,避免matplotlib修改的全局设置影响:
import matplotlib.pyplot as plt import datetime as dt import locale # 保存原始区域设置 original_locale = locale.getlocale(locale.LC_TIME) date = dt.datetime.strptime('02-Jan-2008 10:09:00', '%d-%b-%Y %H:%M:%S') print(date) fig = plt.figure() # 强制切换为英文区域解析日期 locale.setlocale(locale.LC_TIME, 'en_US.UTF-8') date2 = dt.datetime.strptime('02-Jan-2008 10:09:00', '%d-%b-%Y %H:%M:%S') print(date2) # 可选:恢复原始区域设置 locale.setlocale(locale.LC_TIME, original_locale)
方法2:禁止matplotlib修改全局区域设置
修改matplotlib配置,让它不改变系统全局的日期解析区域:
import matplotlib.pyplot as plt import datetime as dt # 创建图形前配置matplotlib使用指定区域,且不自动修改全局设置 plt.rcParams['date.autoformatter.lookup'] = False plt.rcParams['locale'] = 'en_US.UTF-8' date = dt.datetime.strptime('02-Jan-2008 10:09:00', '%d-%b-%Y %H:%M:%S') print(date) fig = plt.figure() date2 = dt.datetime.strptime('02-Jan-2008 10:09:00', '%d-%b-%Y %H:%M:%S') print(date2)
方法3:使用第三方库dateutil解析日期
dateutil的日期解析器默认支持英文月份缩写,不受系统区域影响。先安装库:
conda install python-dateutil
再修改代码:
import matplotlib.pyplot as plt from dateutil import parser date = parser.parse('02-Jan-2008 10:09:00') print(date) fig = plt.figure() date2 = parser.parse('02-Jan-2008 10:09:00') print(date2)
内容的提问来源于stack exchange,提问作者Giuseppe Grieco

