msfmt
Version:
A tiny JavaScript library for parsing and formatting milliseconds into human-readable strings
76 lines (65 loc) • 2.43 kB
JavaScript
const y = 31557600000;
const w = 604800000;
const d = 86400000;
const h = 3600000;
const m = 60000;
const s = 1000;
const msfmt = (val, options = {}) => {
const type = typeof val;
if (type === 'string' && val.length > 0) {
try {
return parse(val);
} catch (err) {
throw new Error(`Invalid time string: ${val}`);
}
} else if (type === 'number' && isFinite(val)) {
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error(`val is not a non-empty string or a valid number. val=${JSON.stringify(val)}`);
};
module.exports = msfmt;
function parse(str) {
str = String(str);
if (str.length > 100) {
throw new Error("String too long");
}
const match = /^(-?(?:\d+\.?\d*|\.\d+)) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);
if (!match) {
throw new Error("Invalid time format");
}
const n = parseFloat(match[1]);
const type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years': case 'year': case 'yrs': case 'yr': case 'y': return n * y;
case 'weeks': case 'week': case 'w': return n * w;
case 'days': case 'day': case 'd': return n * d;
case 'hours': case 'hour': case 'hrs': case 'hr': case 'h': return n * h;
case 'minutes': case 'minute': case 'mins': case 'min': case 'm': return n * m;
case 'seconds': case 'second': case 'secs': case 'sec': case 's': return n * s;
case 'milliseconds': case 'millisecond': case 'msecs': case 'msec': case 'ms': return n;
default: throw new Error("Invalid time unit");
}
}
function fmtShort(ms) {
if (ms === 0) return '0';
const msAbs = Math.abs(ms);
if (msAbs < 1) return "<1ms"
if (msAbs >= d) return Math.round(ms / d) + 'd';
if (msAbs >= h) return Math.round(ms / h) + 'h';
if (msAbs >= m) return Math.round(ms / m) + 'm';
if (msAbs >= s) return Math.round(ms / s) + 's';
return ms + 'ms';
}
function fmtLong(ms) {
if (ms === 0) return '0 ms';
const msAbs = Math.abs(ms);
if (msAbs >= d) return plural(ms, msAbs, d, 'day');
if (msAbs >= h) return plural(ms, msAbs, h, 'hour');
if (msAbs >= m) return plural(ms, msAbs, m, 'minute');
if (msAbs >= s) return plural(ms, msAbs, s, 'second');
return ms + ' ms';
}
function plural(ms, msAbs, n, name) {
const isPlural = msAbs >= n * 1.5;
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
}