diff --git a/index.d.ts b/index.d.ts index e7fc8d6..09a2b94 100644 --- a/index.d.ts +++ b/index.d.ts @@ -22,7 +22,7 @@ declare module './locale/*.js' { declare const durationRE: RegExp; declare namespace parse { - const unit: Units; + let unit: Units; } /** diff --git a/index.js b/index.js index 7d38fa1..bba3cb2 100644 --- a/index.js +++ b/index.js @@ -1,37 +1,36 @@ import en from './locale/en.js' -const durationRE = /(-?(?:\d+\.?\d*|\d*\.?\d+)(?:e[-+]?\d+)?)\s*([\p{L}]*)/uig +const durationRE = /((?:\d{1,16}(?:\.\d{1,16})?|\.\d{1,16})(?:[eE][-+]?\d{1,4})?)\s?([\p{L}]{0,14})/gu parse.unit = en /** * convert `str` to ms * - * @param {String} str - * @param {String} format - * @return {Number} + * @param {string} str + * @param {string} format + * @return {number} */ export default function parse(str = '', format = 'ms') { let result = null, prevUnits - (str + '') - .replace(/(\d)[_ ](\d)/g, '$1$2') // ignore placeholders - .replaceAll(parse.unit.group, '') // remove group separator - .replaceAll(parse.unit.decimal, '.') // normalize decimal separator + String(str) + .replace(new RegExp(`(\\d)[${parse.unit.placeholder}${parse.unit.group}](\\d)`, 'g'), '$1$2') // clean up group separators / placeholders + .replace(parse.unit.decimal, '.') // normalize decimal separator .replace(durationRE, (_, n, units) => { // if no units, find next smallest units or fall back to format value // eg. 1h30 -> 1h30m if (!units) { if (prevUnits) { - for (var u in parse.unit) if (parse.unit[u] < prevUnits) { units = u; break } + for (const u in parse.unit) if (parse.unit[u] < prevUnits) { units = u; break } } else units = format } else units = units.toLowerCase() - units = parse.unit[units] || parse.unit[units.replace(/s$/, '')] + prevUnits = units = parse.unit[units] || parse.unit[units.replace(/s$/, '')] - if (units) result = (result || 0) + Math.abs(parseFloat(n, 10)) * units, prevUnits = units + if (units) result = (result || 0) + n * units }) return result && ((result / (parse.unit[format] || 1)) * (str[0] === '-' ? -1 : 1)) diff --git a/locale/en.js b/locale/en.js index f9595ed..802fbde 100644 --- a/locale/en.js +++ b/locale/en.js @@ -14,5 +14,6 @@ unit.nanosecond = unit.nanosec = unit.ns = 1e-6 unit.group = ',' unit.decimal = '.' +unit.placeholder = ' _' export default unit diff --git a/test.js b/test.js index 6d18f8d..f846782 100644 --- a/test.js +++ b/test.js @@ -167,15 +167,15 @@ t('locales', t => { t('locale separators', t => { parse.unit = en t.equal(parse('3.14 seconds'), 3140) - t.equal(parse('"1,23,456.789 seconds'), 123456789) - t.equal(parse('"1,23,456.789s'), 123456789) - t.equal(parse('"30,000.65 seconds'), 30000650) + t.equal(parse('1,23,456.789 seconds'), 123456789) + t.equal(parse('1,23,456.789s'), 123456789) + t.equal(parse('30,000.65 seconds'), 30000650) parse.unit = de t.equal(parse('3,14 seconds'), 3140) - t.equal(parse('"123.456,789 seconds'), 123456789) - t.equal(parse('"30.000,65 seconds'), 30000650) - t.equal(parse('"30 000,65 seconds'), 30000650) - t.equal(parse('"30_000,65 seconds'), 30000650) + t.equal(parse('123.456,789 seconds'), 123456789) + t.equal(parse('30.000,65 seconds'), 30000650) + t.equal(parse('30 000,65 seconds'), 30000650) + t.equal(parse('30_000,65 seconds'), 30000650) t.end() })