Skip to content

Instantly share code, notes, and snippets.

@sudojunior
Created May 29, 2023 17:32
Show Gist options
  • Save sudojunior/993d08ea77e7425ecb649a7782044813 to your computer and use it in GitHub Desktop.
Save sudojunior/993d08ea77e7425ecb649a7782044813 to your computer and use it in GitHub Desktop.
Timestamp duration conversion
// {second}.{millisecond}
// {minute}:{second}.{millisecond}
// {hour}:{...}
const unitScale = [
1000 /* millsecond -> second */,
60 /* second -> minute */,
60 /* minute -> hour */,
24 /* hour -> day */,
7 /* day -> week */
];
const REGEX = /(?:\d+|-):*\d+\.\d+/;
function getScale(index: number): [number, number] {
if (index < 0) return [NaN, NaN];
let acc = 1;
for (let t = 0; t < index; t++) {
acc *= unitScale[t];
if (t + 1 > unitScale.length) break;
}
return [unitScale[index], acc];
}
function floorBy(amount: number, factor: number): number {
return Math.floor(amount * factor) / factor;
}
function parse(input: string): number {
if (!REGEX.test(input)) {
return NaN;
}
let result = 0;
const segments = input.split(":").reverse();
for (const [index, segment] of segments.entries()) {
// if (segment === '-') continue;
const [, scale] = getScale(index + 1);
result += parseFloat(segment) * scale;
}
return result;
}
function generate(input: number): string {
let result: number[] = [];
for (let index = 0; unitScale.length > index && input >= 0; index++) {
const [unit, scale] = getScale(index + 1);
const remainder = (input / scale) % unit;
if (~~remainder === 0) break;
result.push(floorBy(remainder, index === 0 ? 1000 : 1));
}
return result.reverse().join(':');
}
parse("01:42:39.385")
generate(6159385)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment