0

a project I'm building takes different time lengths from album tracklists in as strings, and I want to add them up cumulatively. The inputs can vary in unpredictability, such as the following list of input time strings:

inputs = ['0:32', '3:19', '11:22']

So I would want to add all these times up like so:

0:32 + 3:19 + 11:22 = = 15:13

I need to make sure the resulting time is a valid timestamp, so incrementing the second/minute/hours realistically is necessary

I figured the best way to do this would be to convert each string time to a python datetime object, but I'm having trouble thinking of how to do this realistically, since all my knowledge and examples I can find of converting a string to a datetime use hard-coded datetime templates, such as:

datetime_str = '09/19/18 13:55:26'
datetime_object = datetime.strptime(datetime_str, '%m/%d/%y %H:%M:%S')

I need to identify multiple different possible string-times, such as :

0:32  = %m:%S
23:19 = %M:%S
01:22:23 = %H:%M:%S
01:2:23 = %H:%m:%S

is there a way to automate this process of adding up multiple different timestamps? My thought process was take the time-string, convert to datetime, convert that datetimeObject to seconds, add them up, then convert it back to dateTime HH:MM:SS format. But I'm getting hung up on how many different possible time inputs I can receive. Any advice is much appreciated as to how I can solve this problem

Martin
  • 1,336
  • 4
  • 32
  • 69

2 Answers2

3

If you know that they all follow this format, it should be doable to parse manually:

def add_times(inputs):
    total_secs=0
    for input in inputs:
        chunks = map(int, reversed(input.split(':')))
        total_secs += sum(chunk*60**i for i,chunk in enumerate(chunks))

    return "{}:{}:{}".format(total_secs//3600, (total_secs%3600)//60, total_secs%60)


print(add_times( ['0:32', '3:19', '11:22']))

gives me 0:15:13.

Ayman
  • 11,265
  • 16
  • 66
  • 92
JoshuaF
  • 1,124
  • 2
  • 9
  • 23
1

For durations, please work with datetime.timedelta. Here’s how to parse your strings into a timedelta, illustrated step by step:

>>> '5:13'.split(':')
['5', '13']
>>> list(map(int, '5:13'.split(':')))
[5, 13]
>>> list(zip(('seconds', 'minutes', 'hours'), map(int, reversed('5:13'.split(':')))))
[('seconds', 13), ('minutes', 5)]
>>> dict(zip(('seconds', 'minutes', 'hours'), map(int, reversed('5:13'.split(':')))))
{'seconds': 13, 'minutes': 5}
>>> timedelta(**dict(zip(('seconds', 'minutes', 'hours'), map(int, reversed('5:13'.split(':'))))))
datetime.timedelta(seconds=313)

Then add up your timedeltas:

from datetime import timedelta
from functools import reduce
from operator import add

def to_timedelta(duration: str) -> timedelta:
    return timedelta(**dict(zip(('seconds', 'minutes', 'hours'), map(int, reversed(duration.split(':'))))))

inputs = ['0:32', '3:19', '11:22']
print(reduce(add, map(to_timedelta, inputs)))
# 0:15:13

A timedelta automatically formats in a nice "H:M:S" format when converted to a string, so there isn't much more you need to do.

deceze
  • 510,633
  • 85
  • 743
  • 889