Human-Readable Duration Formatting
Convert milliseconds into compact durations such as 1h 5m 20s with unit limits, short labels and zero handling.
Code
const UNITS = [
["day", 86400000],
["hour", 3600000],
["minute", 60000],
["second", 1000],
];
// Human-readable duration formatting for elapsed time.
export function formatDuration(milliseconds, options = {}) {
if (typeof milliseconds !== "number" || !Number.isFinite(milliseconds) || milliseconds < 0) {
throw new RangeError("duration must be a non-negative finite number");
}
const { maxUnits = UNITS.length, separator = " ", short = false } = options;
if (!Number.isInteger(maxUnits) || maxUnits < 1) {
throw new RangeError("maxUnits must be a positive integer");
}
let remaining = Math.floor(milliseconds);
const parts = [];
for (const [name, size] of UNITS) {
if (parts.length >= maxUnits) break;
const amount = Math.floor(remaining / size);
remaining -= amount * size;
if (amount === 0 && parts.length === 0) continue;
if (amount === 0) continue;
const label = short ? name[0] : " " + name + (amount === 1 ? "" : "s");
parts.push(amount + label);
}
if (parts.length === 0) return short ? "0s" : "0 seconds";
return parts.join(separator);
}
export function formatDurationClock(milliseconds) {
if (typeof milliseconds !== "number" || !Number.isFinite(milliseconds) || milliseconds < 0) {
throw new RangeError("duration must be a non-negative finite number");
}
const totalSeconds = Math.floor(milliseconds / 1000);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
return [hours, minutes, seconds].map((part) => String(part).padStart(2, "0")).join(":");
}Report a problem with this exampleOpens a pre-filled issue on GitHub.