Подтвердить что ты не робот

Как удалить неотвернутые данные из объекта datetime Python

У меня есть база данных в основном правильные даты, но некоторые из них разбиваются так: Sat Dec 22 12:34:08 PST 20102015

Без недействительного года это работало для меня:

end_date = soup('tr')[4].contents[1].renderContents()
end_date = time.strptime(end_date,"%a %b %d %H:%M:%S %Z %Y")
end_date = datetime.fromtimestamp(time.mktime(end_date))

Но как только я ударил объект с недопустимым годом, я получаю ValueError: unconverted data remains: 2, что здорово, но я не уверен, как лучше всего удалить плохие персонажи из года. Они варьируются от 2 до 6 unconverted characters.

Любые указатели? Я бы просто нарезал end_date, но я надеюсь, что существует стратегия, безопасная для времени и времени.

4b9b3361

Ответ 1

Да, я бы просто отрубил лишние цифры. Предполагая, что они всегда добавляются к дате начала, тогда что-то вроде этого будет работать:

end_date = end_date.split(" ")
end_date[-1] = end_date[-1][:4]
end_date = " ".join(end_date)

Я собирался попытаться получить количество лишних цифр из исключения, но в моих установленных версиях Python (2.6.6 и 3.1.2) эта информация на самом деле отсутствует; он просто говорит, что данные не соответствуют формату. Конечно, вы могли бы просто продолжать отбирать цифры по одному и повторять парсинг, пока не получите исключения.

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

Ответ 2

Если вы не хотите переписать strptime (очень плохая идея), единственная реальная опция, которую вы имеете, - это нарезать end_date и отрубить лишние символы в конце, предполагая, что это даст вам правильный результат. намереваюсь.

Например, вы можете поймать ValueError, срез и повторить попытку:

def parse_prefix(line, fmt):
    try:
        t = time.strptime(line, fmt)
    except ValueError as v:
        if len(v.args) > 0 and v.args[0].startswith('unconverted data remains: '):
            line = line[:-(len(v.args[0]) - 26)]
            t = time.strptime(line, fmt)
        else:
            raise
    return t

Например:

parse_prefix(
    '2015-10-15 11:33:20.738 45162 INFO core.api.wsgi yadda yadda.',
    '%Y-%m-%d %H:%M:%S'
) # -> time.struct_time(tm_year=2015, tm_mon=10, tm_mday=15, tm_hour=11, tm_min=33, ...

Ответ 3

Улучшение (надеюсь) кода Адама Розенфилда:

import time

for end_date in ( 'Fri Feb 18 20:41:47 Paris, Madrid 2011',
                  'Fri Feb 18 20:41:47 Paris, Madrid 20112015'):

    print end_date

    fmt = "%a %b %d %H:%M:%S %Z %Y"
    try:
        end_date = time.strptime(end_date, fmt)
    except ValueError, v:
        ulr = len(v.args[0].partition('unconverted data remains: ')[2])
        if ulr:
            end_date = time.strptime(end_date[:-ulr], fmt)
        else:
            raise v

    print end_date,'\n'

Ответ 4

strptime() действительно ожидает увидеть корректно отформатированную дату, поэтому вам, вероятно, нужно будет немного переманить строку end_date, прежде чем вы ее вызовите.

Это один из способов отрубить последний элемент в end_date до 4 символов:

chop = len(end_date.split()[-1]) - 4
end_date = end_date[:-chop]