import pytz from typing import Optional from datetime import timedelta import re TIME_RE_STRING = r"\s?".join( [ r"((?P\d+?)\s?(weeks?|w))?", r"((?P\d+?)\s?(days?|d))?", r"((?P\d+?)\s?(hours?|hrs|hr?))?", r"((?P\d+?)\s?(minutes?|mins?|m(?!o)))?", # prevent matching "months" r"((?P\d+?)\s?(seconds?|secs?|s))?", ] ) TIME_RE = re.compile(TIME_RE_STRING, re.I) def parse_timedelta(argument: str) -> Optional[timedelta]: matches = TIME_RE.match(argument) if matches: params = {k: int(v) for k, v in matches.groupdict().items() if v} if params: return timedelta(**params) return None def display_time(seconds, granularity=2) -> str: intervals = ( # Source: http://stackoverflow.com/a/24542445 ("weeks", 604800), # 60 * 60 * 24 * 7 ("days", 86400), # 60 * 60 * 24 ("hours", 3600), # 60 * 60 ("minutes", 60), ("seconds", 1), ) result = [] for name, count in intervals: value = int(seconds // count) if value: seconds -= value * count if value == 1: name = name.rstrip("s") result.append("{} {}".format(value, name)) return ", ".join(result[:granularity])