在 Python 中解析非零填充时间戳

我想从时间戳中获取日期时间,如下所示: 3/1/2014 9:55datetime.strptime,或者等价的内容。

The month, day of month, and hour is not zero padded, but there doesn't seem to be a formatting directive listed 给你 that is able to parse this automatically.

这样做的最好方法是什么? 谢谢!

61642 次浏览

strptime能够解析未填充的值。它们在格式化代码表中被标记为填充的事实适用于 strftime的输出。所以你可以用

datetime.strptime(datestr, "%m/%d/%Y %H:%M")

strptime不需要0填充值。参见下面的例子

datetime.strptime("3/1/2014 9:55", "%m/%d/%Y %H:%M")
output:   datetime.datetime(2014, 3, 1, 9, 55)

非模式的方法是使用 dateutil.parse模块,它允许解析常见的日期格式,即使您不知道它当前使用的是什么
例如:

>>> import dateutil.parser
>>>
>>> utc_time     = '2014-08-13T00:00:00'
>>> verbose_time = '13-Aug-2014'
>>> some_locale  = '3/1/2014 9:55'
>>> dateutil.parser.parse(utc_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(verbose_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(some_locale)
datetime.datetime(2014, 3, 1, 9, 55)

以防这个答案对其他人有帮助——我来到这里时认为我在使用零填充时遇到了问题,但实际上这与12:00 vs 00:00和 %I格式化程序有关。

%I格式化程序意味着匹配12小时的时钟小时,可选零填充。但是,根据你的数据来源,你可能会得到的数据说,午夜或中午实际上是零,例如:

>>> datetime.strptime('2015/01/01 0:12am', "%Y/%m/%d %I:%M%p")
ValueError: time data '2015/01/01 0:12am' does not match format '%Y/%m/%d %I:%M'

strptime实际上想要的是12,而不是0:

>>> datetime.strptime('2015/01/01 12:12am', "%Y/%m/%d %I:%M%p")
datetime.datetime(2015, 1, 1, 0, 12)

但是我们并不总是控制我们的数据源!我对这种边缘情况的解决方案是捕获异常,尝试用 %H解析它,并快速检查我们是否处于我们认为处于的边缘情况。

def get_datetime(string):
try:
timestamp = datetime.strptime(string, "%m/%d/%Y %I:%M%p")
except ValueError:
# someone used zero for midnight?
timestamp = datetime.strptime(string, "%m/%d/%Y %H:%M%p")
assert string.lower().endswith('am')
assert timestamp.hour == 0
return timestamp

您可以看到 strftime 文档 给你,但实际上它们并非在所有平台上都工作得很好,例如,%-d,%-m不能在 python 2.7的 win7上工作,所以您可以像这样完成

>>> date_str = '{d.year}-{d.month}-{d.day}'.format(d=datetime.datetime.now())
>>> print(date_str)
2016-5-23