Skip to content

Instantly share code, notes, and snippets.

@gillesdemey
Last active October 4, 2022 09:41
Show Gist options
  • Save gillesdemey/6c251dc4f810d8e60ec2958eb9aa7225 to your computer and use it in GitHub Desktop.
Save gillesdemey/6c251dc4f810d8e60ec2958eb9aa7225 to your computer and use it in GitHub Desktop.
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