generated from sapphiredev/sapphire-template
-
-
Notifications
You must be signed in to change notification settings - Fork 39
/
Duration.ts
123 lines (105 loc) · 2.63 KB
/
Duration.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* eslint-disable @typescript-eslint/restrict-plus-operands */
const tokens = new Map([
['nanosecond', 1 / 1e6],
['nanoseconds', 1 / 1e6],
['ns', 1 / 1e6],
['millisecond', 1],
['milliseconds', 1],
['ms', 1],
['second', 1000],
['seconds', 1000],
['sec', 1000],
['secs', 1000],
['s', 1000],
['minute', 1000 * 60],
['minutes', 1000 * 60],
['min', 1000 * 60],
['mins', 1000 * 60],
['m', 1000 * 60],
['hour', 1000 * 60 * 60],
['hours', 1000 * 60 * 60],
['hr', 1000 * 60 * 60],
['hrs', 1000 * 60 * 60],
['h', 1000 * 60 * 60],
['day', 1000 * 60 * 60 * 24],
['days', 1000 * 60 * 60 * 24],
['d', 1000 * 60 * 60 * 24],
['week', 1000 * 60 * 60 * 24 * 7],
['weeks', 1000 * 60 * 60 * 24 * 7],
['wk', 1000 * 60 * 60 * 24 * 7],
['wks', 1000 * 60 * 60 * 24 * 7],
['w', 1000 * 60 * 60 * 24 * 7],
['month', 1000 * 60 * 60 * 24 * (365.25 / 12)],
['months', 1000 * 60 * 60 * 24 * (365.25 / 12)],
['b', 1000 * 60 * 60 * 24 * (365.25 / 12)],
['mo', 1000 * 60 * 60 * 24 * (365.25 / 12)],
['year', 1000 * 60 * 60 * 24 * 365.25],
['years', 1000 * 60 * 60 * 24 * 365.25],
['yr', 1000 * 60 * 60 * 24 * 365.25],
['yrs', 1000 * 60 * 60 * 24 * 365.25],
['y', 1000 * 60 * 60 * 24 * 365.25]
]);
/**
* Converts duration strings into ms and future dates
*/
export class Duration {
/**
* The offset
*/
public offset: number;
/**
* Create a new Duration instance
* @param pattern The string to parse
*/
public constructor(pattern: string) {
this.offset = Duration.parse(pattern.toLowerCase());
}
/**
* Get the date from now
*/
public get fromNow(): Date {
return this.dateFrom(new Date());
}
/**
* Get the date from
* @param date The Date instance to get the date from
*/
public dateFrom(date: Date): Date {
return new Date(date.getTime() + this.offset);
}
/**
* The RegExp used for the pattern parsing
*/
private static readonly kPatternRegex = /(-?\d*\.?\d+(?:e[-+]?\d+)?)\s*([a-zμ]*)/gi;
/**
* The RegExp used for removing commas
*/
private static readonly kCommaRegex = /,/g;
/**
* The RegExp used for replacing a/an with 1
*/
private static readonly kAanRegex = /\ban?\b/gi;
/**
* Parse the pattern
* @param pattern The pattern to parse
*/
private static parse(pattern: string): number {
let result = 0;
let valid = false;
pattern
// ignore commas
.replace(Duration.kCommaRegex, '')
// a / an = 1
.replace(Duration.kAanRegex, '1')
// do math
.replace(Duration.kPatternRegex, (_, i, units) => {
const token = tokens.get(units);
if (token !== undefined) {
result += Number(i) * token;
valid = true;
}
return '';
});
return valid ? result : NaN;
}
}