Last active
October 4, 2022 09:41
-
-
Save gillesdemey/6c251dc4f810d8e60ec2958eb9aa7225 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const SUFFIX_MULTIPLIER: Record<string, number> = { | |
'ms': 1, | |
's': 1000, | |
'm': 60 * 1000, | |
'h': 60 * 60 * 1000, | |
'd': 24 * 60 * 60 * 1000, | |
'w': 7 * 24 * 60 * 60 * 1000, | |
'y': 365 * 24 * 60 * 60 * 1000, | |
} | |
const DURATION_REGEXP = new RegExp( | |
/^(?:(?<value>\d+)(?<type>ms|s|m|h|d|w|y))|0$/i | |
); | |
function parseDuration(duration: string): number { | |
let input = duration | |
let parts: [number, string][] = []; | |
function matchDuration(part: string) { | |
const match = DURATION_REGEXP.exec(part); | |
const hasValueAndType = Boolean(match?.groups?.value && match?.groups?.type) | |
if (!match || !hasValueAndType) { | |
throw new Error('not a valid duration') | |
} | |
if (match && hasValueAndType) { | |
input = input.replace(match[0], '') | |
parts.push([Number(match.groups.value), match.groups.type]); | |
} | |
if (input) { | |
matchDuration(input); | |
} | |
} | |
matchDuration(duration); | |
if (!parts.length) { | |
throw new Error('not a valid duration') | |
} | |
const totalDuration = parts.reduce((acc, [value, type]) => { | |
const duration = value * SUFFIX_MULTIPLIER[type]; | |
return acc + duration; | |
}, 0); | |
return totalDuration; | |
} | |
parseDuration('2h45m'); // 9900000 | |
parseDuration('2h'); // 7200000 | |
parseDuration('30m'); // 1800000 | |
parseDuration('1s'); // 1000 | |
parseDuration('1d1d'); // 172800000 | |
parseDuration('foo'); // this will throw |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment