138 lines
3.5 KiB
JavaScript
138 lines
3.5 KiB
JavaScript
|
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);
|
||
|
}
|