Преобразование разных форматов времени в один и тот же формат и нахождение разницы между 2 временами

#python #python-3.x #strin& #datetime

#python #python-3.x #строка #дата-время

Вопрос:

Надеюсь, у вас все хорошо получается.

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

Мой пошаговый процесс включает в себя:

  • Преобразование всех данных (первоначально в строковом формате) в формат datetime

  • Поиск случаев, когда времена были выражены по-разному в строковом формате, для правильного преобразования в формат datetime без потери точности PM по-прежнему остается PM и не преобразуется в AM, если уже ‘4’, а не 4PM или 16:00

  • Затем … вычисление разницы между 2 временами (один раз в формате datetime)

Некоторые особенности включают нахождение разницы во времени для следующих времен (сохраненных в виде строк изначально и в этом примере):

  • 16-19
  • 19.30-20.00
  • 17:00-18:00
  • 4-5
  • 5-5.10вечера
  • 16-18 (да, пробел между числами и дефисом является преднамеренным, хотя некоторые манипуляции со строками должны решить это довольно просто)
  • 12 — 14

Мне удалось преобразовать 16-19 в: 16:00:00 и 19:00:00, однако для примера 19.30-20.00 я получаю следующую ошибку: ValueError("unconverted data remains: %s" % ValueError: unconverted data remains: .30 .

Я предполагаю, что это связано с реализацией моего кода:

theDate1, theDate2 = datetime.strptime(temp[0: temp.find('-')], "%H"), datetime.strptime(temp[temp.find('-') 1: len(temp)], "%H")

…где 19.30-20.00 включает в себя часть %M, а не только %H, поэтому в коде не указано, как обращаться с частью :30. Я собирался попробовать условную часть, где, если строка имеет 16-19, запустите некоторый код, а если строка имеет 19.30-20.00, запустите какой-нибудь другой код (и то же самое для других примеров).

Прошу прощения, если мое объяснение немного неуместно… Я нахожусь в свободном пространстве для совместного взлома решения и пробуя все различные комбинации.

Спасибо за любые рекомендации по этому поводу!

Хорошего дня.

Ответ №1:

Что ж, ошибка довольно явная: вы пытаетесь разобрать ‘19.30’ с форматом ‘%H’, который соответствует 19, поэтому ‘.30’ остается непревзойденным.

Использование формата ‘%H.%M’ вместо этого работает для меня 😉

Кроме того, взгляните на dateutil пакет, он предназначен для упрощения синтаксического анализа. Например:

 &&t;&&t;&&t; from datetutil.parser import parse
&&t;&&t;&&t; parse('5PM')
datetime.timedelta(seconds=3600)
&&t;&&t;&&t; parse('19h') - parse('17h45')
datetime.timedelta(seconds=4500)
&&t;&&t;&&t; parse('19:00') - parse('18:30')
datetime.timedelta(seconds=1800)
  

Он действительно мощный и может позаботиться о множестве мелких деталей, таких как пробелы и тому подобное 😉

Комментарии:

1. к сожалению, анализатор dateutil не будет сразу анализировать все строки примера OP..

Ответ №2:

вот способ проанализировать строки примера с помощью парсера dateutil после небольшой предварительной обработки:

 from dateutil import parser

strin&s = ['16-19', '19.30-20.00', '5PM-6PM', '4-5' ,'5-5.10PM', '16 - 18', '12 - 14']
datepfx = '2020-07-21 ' # will prefix this so parser.parse works correctly

for s in strin&s:
    # split on '-', strip trailin& spaces
    # replace . with : as time separator, ensure upper-case letters
    parts = [part.strip().replace('.',':').upper() for part in s.split('-')]
    # if only one number is &iven, assume hour and add minute :00
    parts = [p ':00' if len(p)==1 else p for p in parts]
    # check if AM or PM appears in only one of the parts
    ampm = [i for i in ('AM', 'PM') for p in parts if i in p]
    if len(ampm) == 1:
        parts = [p ampm[0] if not ampm[0] in p else p for p in parts]      

    print(f"n'{s}' processed to -&&t; {parts}")
    print([parser.parse(datepfx   p).time() for p in parts])
  

дает

 '16-19' processed to -&&t; ['16', '19']
[datetime.time(16, 0), datetime.time(19, 0)]

'19.30-20.00' processed to -&&t; ['19:30', '20:00']
[datetime.time(19, 30), datetime.time(20, 0)]

'5PM-6PM' processed to -&&t; ['5PM', '6PM']
[datetime.time(17, 0), datetime.time(18, 0)]

'4-5' processed to -&&t; ['4:00', '5:00']
[datetime.time(4, 0), datetime.time(5, 0)]

'5-5.10PM' processed to -&&t; ['5:00PM', '5:10PM']
[datetime.time(17, 0), datetime.time(17, 10)]

'16 - 18' processed to -&&t; ['16', '18']
[datetime.time(16, 0), datetime.time(18, 0)]

'12 - 14' processed to -&&t; ['12', '14']
[datetime.time(12, 0), datetime.time(14, 0)]