Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ declare module './locale/*.js' {
declare const durationRE: RegExp;

declare namespace parse {
const unit: Units;
let unit: Units;
}

/**
Expand Down
21 changes: 10 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
@@ -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))
Expand Down
1 change: 1 addition & 0 deletions locale/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ unit.nanosecond = unit.nanosec = unit.ns = 1e-6

unit.group = ','
unit.decimal = '.'
unit.placeholder = ' _'

export default unit
14 changes: 7 additions & 7 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})