const DURATION_UNIT_TO_MS: Record = { ns: 1e-6, us: 1e-3, '\u00b5s': 1e-3, ms: 1, s: 1_000, m: 60_000, h: 3_600_000, } const DURATION_PART_REGEX = /^(\d+(?:\.\d+)?|\.\d+)(ns|us|\u00b5s|ms|s|m|h)/ export function ParseDuration(s: string): number { // discuss at: https://locutus.io/golang/time/ParseDuration // parity verified: Go 1.23 // original by: Kevin van Zonneveld (https://kvz.io) // note 1: Parses Go duration strings and returns milliseconds. // note 2: Supports ns, us/µs, ms, s, m, h units and chained segments. // example 1: ParseDuration('300ms') // returns 1: 300 // example 2: ParseDuration('1h2m3.5s') // returns 2: 3723500 // example 3: ParseDuration('-1.5h') // returns 3: -5400000 // example 4: ParseDuration('2h45m') // returns 4: 9900000 const raw = String(s).trim() if (raw === '') { throw new TypeError('ParseDuration(): invalid duration') } let sign = 1 let rest = raw if (rest.startsWith('+') || rest.startsWith('-')) { sign = rest[0] === '-' ? -1 : 1 rest = rest.slice(1) } if (rest === '0') { return 0 } let totalMs = 0 while (rest.length > 0) { const match = DURATION_PART_REGEX.exec(rest) if (!match) { throw new TypeError('ParseDuration(): invalid duration') } const valueLiteral = match[1] const unit = match[2] if (!valueLiteral || !unit) { throw new TypeError('ParseDuration(): invalid duration') } const value = Number.parseFloat(valueLiteral) const multiplier = DURATION_UNIT_TO_MS[unit] if (!Number.isFinite(value) || multiplier === undefined) { throw new TypeError('ParseDuration(): invalid duration') } totalMs += value * multiplier rest = rest.slice(match[0].length) } return sign * totalMs }