1 |
|
2 | const moment = require('moment');
|
3 |
|
4 |
|
5 | const secondUnit = 'second';
|
6 | const minuteUnit = 'minute';
|
7 | const hourUnit = 'hour';
|
8 | const dayUnit = 'day';
|
9 |
|
10 |
|
11 | const timeReprMap = {
|
12 | s: secondUnit,
|
13 | sec: secondUnit,
|
14 | second: secondUnit,
|
15 | seconds: secondUnit,
|
16 | m: minuteUnit,
|
17 | min: minuteUnit,
|
18 | mins: minuteUnit,
|
19 | minute: minuteUnit,
|
20 | minutes: minuteUnit,
|
21 | h: hourUnit,
|
22 | hr: hourUnit,
|
23 | hour: hourUnit,
|
24 | hours: hourUnit,
|
25 | d: dayUnit,
|
26 | day: dayUnit,
|
27 | days: dayUnit,
|
28 | };
|
29 |
|
30 |
|
31 |
|
32 | const onlyNumeric = /^[0-9]+$/g;
|
33 |
|
34 | const offsetFormat = /^[0-9]+[a-z]+$/g;
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | const fromOffset = function fromOffset(offset) {
|
52 |
|
53 |
|
54 | const timePart = offset.match(/[0-9]+.*?(?=[^0-9])/);
|
55 | const realTime = parseInt(timePart);
|
56 |
|
57 | if (isNaN(realTime)) {
|
58 | throw new Error(`Invalid offset format "${offset}", time portion was ${realTime}`);
|
59 | }
|
60 |
|
61 | const textPart = offset.match(/[a-z]+/);
|
62 |
|
63 | const textRepr = timeReprMap[textPart];
|
64 | if (!textRepr || !textPart) {
|
65 | throw new Error(`Invalid offset format, unknown unit "${offset.slice(timePart.toString().length, offset.length)}"`);
|
66 | }
|
67 |
|
68 | const calculatedTime = moment();
|
69 | calculatedTime.subtract(realTime, textRepr);
|
70 | return calculatedTime;
|
71 | };
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 | const parseTimeString = function parseTimeString(timeString) {
|
83 | const attemptISO = moment(timeString, moment.ISO_8601);
|
84 |
|
85 | if (onlyNumeric.test(timeString)) {
|
86 | const parsedNumber = parseInt(timeString.replace('.', ''));
|
87 | const timestamp = moment(parsedNumber);
|
88 | if (timestamp.isValid()) {
|
89 | return timestamp;
|
90 | }
|
91 | throw new Error(`Invalid numeric timestamp format "${timeString}"`);
|
92 | } else if (attemptISO.isValid()) {
|
93 | return attemptISO;
|
94 | } else if (offsetFormat.test(timeString)) {
|
95 | return fromOffset(timeString);
|
96 | }
|
97 | throw new Error(`Invalid time format "${timeString}"`);
|
98 | };
|
99 |
|
100 | module.exports = {
|
101 | parseTimeString,
|
102 | };
|