Functional Weave
Code in Rust

monitor.format-duration@1.0.0

impl/python.py

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")."""
    if not 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)
    if not isinstance(max_units, int) or isinstance(max_units, bool) or max_units < 1 or max_units > 4:
        raise ValueError("maxUnits must be 1 to 4, received %r" % (max_units,))
    if seconds == 0:
        return "0s"
    first = 0
    while 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)