const UNITS: Record = { ms: 1, s: 1_000, m: 60_000, h: 3_600_000, d: 86_400_000 }; export function parseDuration(input: string): number { const value = input.trim(); if (!value) throw new Error("Duração vazia."); let total = 0; let end = 0; const pattern = /(\d+(?:\.\d+)?)(ms|s|m|h|d)/gy; while (end < value.length) { pattern.lastIndex = end; const match = pattern.exec(value); if (!match) throw new Error(`Duração inválida: ${input}`); const amount = Number(match[1]); if (!Number.isFinite(amount) || amount <= 0) throw new Error(`Duração deve ser positiva: ${input}`); total += amount * UNITS[match[2]]; if (!Number.isSafeInteger(total) || total > 2_147_483_647) throw new Error(`Duração excede o limite suportado: ${input}`); end = pattern.lastIndex; } if (!Number.isInteger(total)) throw new Error(`Duração deve resultar em milissegundos inteiros: ${input}`); return total; } export function formatDuration(ms: number): string { if (ms <= 0) return "0s"; const units: Array<[string, number]> = [["d", 86_400_000], ["h", 3_600_000], ["m", 60_000], ["s", 1_000], ["ms", 1]]; let rest = Math.floor(ms); const parts: string[] = []; for (const [label, size] of units) { const amount = Math.floor(rest / size); if (amount) { parts.push(`${amount}${label}`); rest -= amount * size; } } return parts.join(""); }