968 bytes · the TypeScript implementation · view raw
import { type Countdown } from"./time_countdown_types.ts";
function pad2(n: number): string {
return n < 10 ? "0" + n : String(n);
}
/** * 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: "on or * after"), so `now === until` is expired with nothing left. */exportfunction countdown(until: number, now: number): Countdown {
if (typeof until !== "number" || !Number.isSafeInteger(until)) thrownew RangeError("until must be a whole number of seconds");
if (typeof now !== "number" || !Number.isSafeInteger(now)) thrownew RangeError("now must be a whole number of seconds");
const seconds = until > now ? until - now : 0;
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;
const text = h > 0 ? `${h}:${pad2(m)}:${pad2(s)}` : `${m}:${pad2(s)}`;
return { expired: seconds === 0, seconds, text };
}