utils.mjs
3.51 KB
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import {
millisecondsInHour,
millisecondsInMinute,
millisecondsInSecond,
} from "../../constants.mjs";
import { numericPatterns } from "./constants.mjs";
export function mapValue(parseFnResult, mapFn) {
if (!parseFnResult) {
return parseFnResult;
}
return {
value: mapFn(parseFnResult.value),
rest: parseFnResult.rest,
};
}
export function parseNumericPattern(pattern, dateString) {
const matchResult = dateString.match(pattern);
if (!matchResult) {
return null;
}
return {
value: parseInt(matchResult[0], 10),
rest: dateString.slice(matchResult[0].length),
};
}
export function parseTimezonePattern(pattern, dateString) {
const matchResult = dateString.match(pattern);
if (!matchResult) {
return null;
}
// Input is 'Z'
if (matchResult[0] === "Z") {
return {
value: 0,
rest: dateString.slice(1),
};
}
const sign = matchResult[1] === "+" ? 1 : -1;
const hours = matchResult[2] ? parseInt(matchResult[2], 10) : 0;
const minutes = matchResult[3] ? parseInt(matchResult[3], 10) : 0;
const seconds = matchResult[5] ? parseInt(matchResult[5], 10) : 0;
return {
value:
sign *
(hours * millisecondsInHour +
minutes * millisecondsInMinute +
seconds * millisecondsInSecond),
rest: dateString.slice(matchResult[0].length),
};
}
export function parseAnyDigitsSigned(dateString) {
return parseNumericPattern(numericPatterns.anyDigitsSigned, dateString);
}
export function parseNDigits(n, dateString) {
switch (n) {
case 1:
return parseNumericPattern(numericPatterns.singleDigit, dateString);
case 2:
return parseNumericPattern(numericPatterns.twoDigits, dateString);
case 3:
return parseNumericPattern(numericPatterns.threeDigits, dateString);
case 4:
return parseNumericPattern(numericPatterns.fourDigits, dateString);
default:
return parseNumericPattern(new RegExp("^\\d{1," + n + "}"), dateString);
}
}
export function parseNDigitsSigned(n, dateString) {
switch (n) {
case 1:
return parseNumericPattern(numericPatterns.singleDigitSigned, dateString);
case 2:
return parseNumericPattern(numericPatterns.twoDigitsSigned, dateString);
case 3:
return parseNumericPattern(numericPatterns.threeDigitsSigned, dateString);
case 4:
return parseNumericPattern(numericPatterns.fourDigitsSigned, dateString);
default:
return parseNumericPattern(new RegExp("^-?\\d{1," + n + "}"), dateString);
}
}
export function dayPeriodEnumToHours(dayPeriod) {
switch (dayPeriod) {
case "morning":
return 4;
case "evening":
return 17;
case "pm":
case "noon":
case "afternoon":
return 12;
case "am":
case "midnight":
case "night":
default:
return 0;
}
}
export function normalizeTwoDigitYear(twoDigitYear, currentYear) {
const isCommonEra = currentYear > 0;
// Absolute number of the current year:
// 1 -> 1 AC
// 0 -> 1 BC
// -1 -> 2 BC
const absCurrentYear = isCommonEra ? currentYear : 1 - currentYear;
let result;
if (absCurrentYear <= 50) {
result = twoDigitYear || 100;
} else {
const rangeEnd = absCurrentYear + 50;
const rangeEndCentury = Math.trunc(rangeEnd / 100) * 100;
const isPreviousCentury = twoDigitYear >= rangeEnd % 100;
result = twoDigitYear + rangeEndCentury - (isPreviousCentury ? 100 : 0);
}
return isCommonEra ? result : 1 - result;
}
export function isLeapYearIndex(year) {
return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);
}