时间数据与格式 '%c'

问题描述

这是非常出乎意料的行为...

  1. 我使用 '%c' 指令创建了一个时间字符串。

    %cLocale’s appropriate date and time representation

  2. 然后我尝试解析生成的时间字符串,指定与字符串格式相同的 '%c'

  3. 但是,正如您从下面的错误中看到的那样,这不起作用。我错过了什么?

我需要能够将时间存储在人类可读的本地化字符串中,然后将字符串转换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 内置库“更智能”,并正确支持多种语言环境