问题描述
这是非常出乎意料的行为...
我需要能够将时间存储在人类可读的本地化字符串中,然后将字符串转换回 struct_time
以便我可以从中提取信息。 >
(字符串的本地化非常重要,我当然不想为世界各地的所有语言环境编写解析算法!)
# Ensure the locale is set.
import locale
locale.setlocale(locale.LC_ALL,'')
'en_US.UTF-8'
# 1. Create a localized time string using the '%c' directive.
import datetime
time_stamp = datetime.datetime.Now().strftime('%c')
time_stamp
'Mon 21 Dec 2020 03:47:55 PM '
# 2. Try to parse the string using the same directive used to create it.
import time
time.strptime(time_stamp,'%c')
# 3. Unexpected error...
Traceback (most recent call last):
File "<stdin>",line 1,in <module>
File "/usr/lib/python3.8/_strptime.py",line 562,in _strptime_time
tt = _strptime(data_string,format)[0]
File "/usr/lib/python3.8/_strptime.py",line 349,in _strptime
raise ValueError("time data %r does not match format %r" %
ValueError: time data 'Mon 21 Dec 2020 03:47:55 PM ' does not match format '%c'
解决方法
您可以使用 %a、%b 和其他指令指定您希望如何格式化日期,而不是使用 %c。例如:
import locale
locale.setlocale(locale.LC_ALL,'en_US.utf-8')
import datetime
fmt = '%a %b %d %Y %H:%M:%S'
time_stamp = datetime.datetime.now().strftime(fmt)
print(time_stamp)
import time
print(time.strptime(time_stamp,fmt))
这会产生您正在寻找的输出:
输出:
Mon Dec 21 2020 21:27:50
time.struct_time(tm_year=2020,tm_mon=12,tm_mday=21,tm_hour=21,tm_min=27,tm_sec=50,tm_wday=0,tm_yday=356,tm_isdst=-1)
,
您的语言环境可能没有按照您期望的方式配置 .strftime("%c")
,并且 .strptime
反对后缀 %p
(PM
)
改用 locale.nl_langinfo(locale.D_T_FMT)
来构建您的格式!
>>> locale.nl_langinfo(locale.D_T_FMT)
'%a %b %e %H:%M:%S %Y'
>>> locale.setlocale(locale.LC_ALL,'')
'en_US.UTF-8'
>>> locale.nl_langinfo(locale.D_T_FMT)
'%a %b %e %X %Y'
但是,如果你
- ...知道输出的确切结构,使用正则表达式过滤精确匹配,然后解析
- ...可以控制格式,不用去格式化直接用
time.time()
- .. 或始终以 UTC 格式工作,格式为 ISO 8601,派生 tz-aware 对象并使用自定义解析器回读(请参阅 the Caution on
.fromisoformat
)>>> datetime.datetime.now(tz=datetime.timezone.utc) datetime.datetime(2020,12,22,4,29,537007,tzinfo=datetime.timezone.utc)
- 使用
pytz
,它比 datetime 内置库“更智能”,并正确支持多种语言环境