简体   繁体   中英

Converting different time formats into same format and finding difference between 2 times

Hope you're all doing good.

I've been working this particular problem of finding the time difference between 2 times (that are in all different formats). I have partially solved it for some cases, however cannot understand at the moment how to create a solution for all cases.

My step by step process includes:

  • Converting all data (originally in String format) into datetime format

  • Finding cases where times have been expressed differently in String format to properly convert into datetime format without losing accuracy of PM is still PM and not converted into AM if it's '4' and not 4PM or 16:00 already

  • Then... calculating the difference between 2 times (once in datetime format)

Some specifics include finding the time difference for the following times (stored as Strings originally and in this example):

  • 16-19
  • 19.30-20.00
  • 5PM-6PM
  • 4-5
  • 5-5.10PM
  • 16 - 18 (yes the space between the numbers and hyphen is intentional, although some string manipulation should resolve this quite simply)
  • 12 - 14

I've managed to convert the 16-19 into: 16:00:00 and 19:00:00, however for the 19.30-20.00 example, i receive the following error: ValueError("unconverted data remains: %s" % ValueError: unconverted data remains: .30 .

I'm assuming this is due to my code implementation:

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

...where the 19.30-20.00 includes a %M part and not only a %H so the code doesn't say how to deal with the:30 part. I was going to try a conditional part where if the string has 16-19, run some code and if the string has 19.30-20.00 run some other code (and the same for the other examples).

Apologies if my explanation is a bit all over the place... I'm in the headspace of hacking a solution together and trying all different combinations.

Thanks for any guidance with this!

Have a good day.

Well the error is pretty explicit: you're trying to parse '19.30' with format '%H', which matches 19, so the '.30' is left unmatched.

Using format '%H.%M' instead works for me;)

Also, have a look at the dateutil package, it's meant to make parsing easier. For example:

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

It's really powerful and can take care of a lot a little details like whitespaces and such;)

here's a way to parse the example strings using dateutil 's parser, after a little pre-processing:

from dateutil import parser

strings = ['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 strings:
    # split on '-', strip trailing 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 given, 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 -> {parts}")
    print([parser.parse(datepfx + p).time() for p in parts])

gives

'16-19' processed to -> ['16', '19']
[datetime.time(16, 0), datetime.time(19, 0)]

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

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

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

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

'16 - 18' processed to -> ['16', '18']
[datetime.time(16, 0), datetime.time(18, 0)]

'12 - 14' processed to -> ['12', '14']
[datetime.time(12, 0), datetime.time(14, 0)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM