kel5isgod
kel5isgod

Reputation: 33

Python function to split up a duration string

all! I'm making a Discord bot, and with the ban command, will come a way to ban someone for a specified time. Duration strings will go up to days. A full string may look something like these:
1d / 5h30m / 14d / 10m
I'm looking for a way to parse these strings and get something back like {"minutes": 10, "hours": 5}
It doesn't need to be a dictionary, just something where I can tell which unit of time it is and multiply it to get how long the ban should last. Any ideas are appreciated!

Upvotes: 0

Views: 473

Answers (2)

theFrok
theFrok

Reputation: 355

I found this package called durations (which can be installed from pip), and it does exactly what you need. (don't confuse it with duration).

From their readme examples:

>>> from durations import Duration

>>> one_hour = '1hour'

>>> one_hour_duration = Duration(one_hour)
>>> one_hour_duration.to_seconds()
3600.0
>>> one_hour_duration.to_minutes()
60.0


# You can even compose durations in their short
# and long variations
>>> two_days_three_hours = '2 days, 3h'
>>> two_days_three_hours_duration = Duration(two_days_three_hours)
>>> two_days_three_hours_duration.to_seconds()
183600.0
>>> two_days_three_hours_duration.to_hours()
51.0

Upvotes: 1

hilberts_drinking_problem
hilberts_drinking_problem

Reputation: 11602

You could use regular expressions to parse the time string, and use datetime to convert to the desired unit of measurement, e.g. seconds:

import re, datetime

test_str = '0d20h30m'

conv_dict = {
    'd': 'days',
    'h': 'hours',
    'm': 'minutes',
    's': 'seconds',
}

pat = r'[0-9]+[s|m|h|d]{1}'
def timestr_to_dict(tstr):
  'e.g. convert 1d2h3m4s to {"d": 1, "h": 2, "m": 3, "s": 4}'
  return {conv_dict[p[-1]]: int(p[:-1]) for p in re.findall(pat, test_str)}

print(timestr_to_dict(test_str))
{'days': 0, 'hours': 20, 'minutes': 30}

def timestr_to_seconds(tstr):
  return datetime.timedelta(**timestr_to_dict(tstr)).total_seconds()

print(timestr_to_seconds(test_str))
# 73800.0

Upvotes: 1

Related Questions