0

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

9

У меня есть база данных с в основном правильными датами и временами, но несколько записей повреждены, например: <code>Sat Dec 22 12:34:08 PST 20102015</code>.

Без неверного года код работал для меня следующим образом:

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))

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

Можете дать несколько советов? Я бы мог просто обрезать <code>end_date</code>, но надеюсь найти безопасную для datetime стратегию.

5 ответ(ов)

0

Если вы не хотите переписывать функцию 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, ...
0

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

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

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

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

0

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

end_date = end_date[:-4]

Этот код обрезает последние четыре символа строки end_date.

0

Ваш код содержит несколько моментов, которые можно улучшить для повышения его читаемости и надежности. Я также рекомендую использовать более современный синтаксис Python и улучшить обработку исключений. Ниже приведён переработанный вариант вашего кода:

import time

def parse_end_dates(end_dates):
    fmt = "%a %b %d %H:%M:%S %Z %Y"

    for end_date in end_dates:
        print(end_date)
        
        try:
            parsed_date = time.strptime(end_date, fmt)
        except ValueError as e:
            unconverted_data_length = len(e.args[0].partition('unconverted data remains: ')[2])
            if unconverted_data_length:
                parsed_date = time.strptime(end_date[:-unconverted_data_length], fmt)
            else:
                raise

        print(parsed_date, '\n')

end_dates = [
    'Fri Feb 18 20:41:47 Paris, Madrid 2011',
    'Fri Feb 18 20:41:47 Paris, Madrid 20112015'
]

parse_end_dates(end_dates)

Основные изменения:

  1. Функция: Я обернул основной код в функцию parse_end_dates, что делает его более организованным и повторно используемым.
  2. Печать: Обновил синтаксис print, чтобы он соответствовал Python 3 (если вы используете более ранние версии, вернитесь к старому стилю печати).
  3. Обработка исключений: Изменил синтаксис обработки исключений с except ValueError, v: на except ValueError as e:. Это более современный и понятный способ.
  4. Чтение переменной: Переименовал переменные для большей читаемости, например, v на e и ulr на unconverted_data_length.

Теперь ваш код стал более понятным и соответствует современным стандартам Python.

0

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

Вот один из способов убрать последние символы в end_date, оставив только 4 символа в конце:

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

Обратите внимание, что данный код предполагает, что в конце строки end_date находится элемент, у которого длина больше 4 символов. Убедитесь, что ваша строка соответствует этому условию, чтобы избежать возможных ошибок.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь