Разбор ненулевых заполненных временных меток в Python


84

Я хочу получать дату и время из временных меток, например следующих: 3/1/2014 9:55с datetime.strptimeили что-то подобное.

Месяц, день месяца, час не равен нулю проложенный, но не похоже, чтобы быть форматированием директивы перечислены здесь , который способен анализировать это автоматически.

Как лучше всего это сделать? Благодаря!

Ответы:


131

strptimeможет анализировать значения без дополнений. Тот факт, что они отмечены как заполненные в таблице кодов форматирования, относится и к strftimeвыходным данным . Так что вы можете просто использовать

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

8

strptimeisdo не требует значений, дополненных нулями. См. Пример ниже

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

2

На всякий случай, этот ответ поможет кому-то другому - я пришел сюда, думая, что у меня проблема с нулевым заполнением, но на самом деле это было связано с 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:
        # 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

0:12amневерный ввод. Так и должно быть 12:12am. 11:59 pmследует 12:00 am, не 0:00am. Могут быть разные способы предоставления данных в неправильном формате времени, например, ввод может использовать двузначный год ( %y) вместо четырехзначного года ( %Y), или день / месяц могут быть поменяны местами ( %m/%dvs. %d/%m) и т. Д. День / Случай месяца может быть двусмысленным, например, 2015/10/12это «12 октября» или «10 декабря»? кстати, вы должны использовать %Y/%m/%dвместо того, %m/%d/%Yчтобы соответствовать вашему формату ввода.
jfs

Спасибо, я понимаю, что это неверный ввод, как я уже сказал, он исходит из источника данных, который я не контролирую.
hwjp

2

Вы можете увидеть здесь документ 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

1
В родной Windows хеш заменяется тире: %#d, %#m. Но и тире, и хеш-моды нужны только в string formatting ( strftime), а не в parsing ( strptime).
Nuno André

1

Не-шаблонный способ - это использовать 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)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.