from .time_countdown_types import Countdown def _whole(value: object) -> bool: # bool is an int in Python; True is not a number of seconds. return isinstance(value, int) and not isinstance(value, bool) def countdown(until: int, now: int) -> Countdown: """The time left until `until`, as a number and as a timer's text. A moment is reached at `until` itself, as a JWT's exp is (RFC 7519 4.1.4), so now == until is expired with nothing left.""" if not _whole(until): raise ValueError("until must be a whole number of seconds") if not _whole(now): raise ValueError("now must be a whole number of seconds") seconds = until - now if until > now else 0 h, rest = divmod(seconds, 3600) m, s = divmod(rest, 60) text = "%d:%02d:%02d" % (h, m, s) if h > 0 else "%d:%02d" % (m, s) return Countdown(expired=seconds == 0, seconds=seconds, text=text)