Как удалить неконвертированные данные из объекта даты и времени Python - PullRequest
25 голосов
/ 18 февраля 2011

У меня есть база данных с наиболее правильными датами, но некоторые из них разбиты примерно так: 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, но я надеюсь, что есть стратегия, безопасная для даты и времени.

Ответы [ 5 ]

16 голосов
/ 18 февраля 2011

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

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

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

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

15 голосов
/ 18 февраля 2011

Если вы не хотите переписать 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, ...
5 голосов
/ 18 февраля 2011

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

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'
1 голос
/ 07 сентября 2018

Вот еще более простой однострочный текст, который я использую:

end_date = end_date[:-4]

0 голосов
/ 18 февраля 2011

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

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

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