На всякий случай, этот ответ поможет кому-то другому - я пришел сюда, думая, что у меня проблема с нулевым заполнением, но на самом деле это было связано с 12:00 против 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, а не ноль:
>>> 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:
timestamp = datetime.strptime(string, "%m/%d/%Y %H:%M%p")
assert string.lower().endswith('am')
assert timestamp.hour == 0
return timestamp
0:12am
неверный ввод. Так и должно быть12:12am
.11:59 pm
следует12:00 am
, не0:00am
. Могут быть разные способы предоставления данных в неправильном формате времени, например, ввод может использовать двузначный год (%y
) вместо четырехзначного года (%Y
), или день / месяц могут быть поменяны местами (%m/%d
vs.%d/%m
) и т. Д. День / Случай месяца может быть двусмысленным, например,2015/10/12
это «12 октября» или «10 декабря»? кстати, вы должны использовать%Y/%m/%d
вместо того,%m/%d/%Y
чтобы соответствовать вашему формату ввода.Вы можете увидеть здесь документ strftime , но на самом деле они не все хорошо работают на всех платформах , например ,
%-d,%-m
не работают на win7 с помощью python 2.7 , так что вы можете сделать это>>> date_str = '{d.year}-{d.month}-{d.day}'.format(d=datetime.datetime.now()) >>> print(date_str) 2016-5-23
источник
%#d
,%#m
. Но и тире, и хеш-моды нужны только в string formatting (strftime
), а не в parsing (strptime
).Не-шаблонный способ - это использовать
dateutil.parse
модуль, он позволяет анализировать общие форматы даты, даже если вы не знаете, что он использует в настоящее времяEx:
>>> 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)
источник