-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathformatDuration.ts
61 lines (49 loc) · 1.65 KB
/
formatDuration.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* Formats a duration in milliseconds into English text.
* @param duration - The duration in milliseconds
* @param style - The style to format the duration in
* @returns The formatted duration
*/
export const formatDuration = (duration: number, style = DurationStyle.For): string => {
if (duration === Infinity) return 'indefinitely';
duration = Math.round(duration / 1000);
if (duration < 0) {
const core = _formatDuration(-duration);
if (style === DurationStyle.Blank) return `negative ${core}`;
if (style === DurationStyle.For) return `for negative ${core}`;
if (style === DurationStyle.Until) return `until ${core} ago`;
}
if (duration === 0) {
if (style === DurationStyle.Blank) return 'no time';
if (style === DurationStyle.For) return 'for no time';
if (style === DurationStyle.Until) return 'until right now';
}
const core = _formatDuration(duration);
if (style === DurationStyle.Blank) return core;
if (style === DurationStyle.For) return `for ${core}`;
if (style === DurationStyle.Until) return `until ${core} from now`;
return '??';
};
function _formatDuration(duration: number): string {
if (duration === Infinity) return 'indefinitely';
const parts: string[] = [];
for (const [name, scale] of formatTimescales) {
if (duration >= scale) {
const amount = Math.floor(duration / scale);
duration %= scale;
parts.push(`${amount} ${name}${amount === 1 ? '' : 's'}`);
}
}
return parts.join(' ');
}
export enum DurationStyle {
Blank,
For,
Until,
}
const formatTimescales: [string, number][] = [
['day', 86400],
['hour', 3600],
['minute', 60],
['second', 1],
];