1,344 bytes · the Python implementation · view raw
from typing import List
_UNITS = (("d", 86400), ("h", 3600), ("m", 60), ("s", 1))
def format_duration(seconds: int, max_units: int) -> str:
"""Seconds as "3h 12m". Starts at the largest non-zero unit and looks at max_units consecutive units from there, leaving out the zero ones, so 3605 s with two units is "1h", not "1h 0m" and not "1h 5s": the seconds are beyond the precision asked for. Truncates, never rounds up, so a duration is never shown longer than it was (86399 s is "23h", not "1d")."""ifnot isinstance(seconds, int) or isinstance(seconds, bool):
raise ValueError("seconds must be a whole number, received %r" % (seconds,))
if seconds < 0:
raise ValueError("seconds must not be negative, received %d" % seconds)
ifnot isinstance(max_units, int) or isinstance(max_units, bool) or max_units < 1or max_units > 4:
raise ValueError("maxUnits must be 1 to 4, received %r" % (max_units,))
if seconds == 0:
return"0s"
first = 0while seconds // _UNITS[first][1] == 0:
first += 1
parts: List[str] = []
rest = seconds
for i, (label, size) in enumerate(_UNITS):
n = rest // size
rest -= n * size
if first <= i < first + max_units and n > 0:
parts.append("%d%s" % (n, label))
return" ".join(parts)