276 lines
7.2 KiB
Plaintext
276 lines
7.2 KiB
Plaintext
"use strict";
|
|
const compile = require("./compile.js");
|
|
const normalizeUnit = require("./normalizeUnit-Cn0hUyBC.js");
|
|
const units = require("./units.js");
|
|
const BASIC_ISO_REGEX = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
|
|
const EXTENDED_ISO_REGEX = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
|
|
const ISO_TIMES_REGEX = [
|
|
/(\d\d):(\d\d):(\d\d)\.(\d+)/,
|
|
// 'HH:mm:ss.SSSS'
|
|
/(\d\d):(\d\d):(\d\d),(\d+)/,
|
|
// 'HH:mm:ss,SSSS'
|
|
/(\d\d):(\d\d):(\d\d)/,
|
|
// 'HH:mm:ss'
|
|
/(\d\d):(\d\d)/,
|
|
// 'HH:mm'
|
|
/(\d\d)(\d\d)(\d\d)\.(\d+)/,
|
|
// 'HHmmss.SSSS'
|
|
/(\d\d)(\d\d)(\d\d),(\d+)/,
|
|
// 'HHmmss,SSSS'
|
|
/(\d\d)(\d\d)(\d\d)/,
|
|
// 'HHmmss'
|
|
/(\d\d)(\d\d)/,
|
|
// 'HHmm'
|
|
/(\d\d)/
|
|
// 'HH'
|
|
];
|
|
const TZ_REGEX = /(Z)|([+-]\d\d)(?::?(\d\d))?/;
|
|
const ISO_DATES_REGEX = [
|
|
/(\d{4})-(\d\d)-(\d\d)/,
|
|
// 'YYYY-MM-DD'
|
|
/(\d{4})-(\d\d)/,
|
|
// 'YYYY-MM'
|
|
/(\d{4})(\d\d)(\d\d)/,
|
|
// 'YYYYMMDD'
|
|
/(\d{4})(\d\d)/,
|
|
// 'YYYYMM'
|
|
/(\d{4})/
|
|
// 'YYYY'
|
|
];
|
|
function autoExtract(input) {
|
|
const dateRet = new Array(8);
|
|
let matches;
|
|
const match = EXTENDED_ISO_REGEX.exec(input) || BASIC_ISO_REGEX.exec(input);
|
|
if (match) {
|
|
const datesLen = ISO_DATES_REGEX.length;
|
|
for (let i = 0; i < datesLen; i++) {
|
|
if (matches = ISO_DATES_REGEX[i].exec(match[1])) {
|
|
for (let j = 0; j < 3; j++) {
|
|
const matched = matches[j + 1];
|
|
dateRet[j] = matched ? +matched : 1;
|
|
}
|
|
if (dateRet[1]) {
|
|
dateRet[1] -= 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
matches = null;
|
|
if (match[3]) {
|
|
for (let i = 0, timesLen = ISO_TIMES_REGEX.length; i < timesLen; i++) {
|
|
if (matches = ISO_TIMES_REGEX[i].exec(match[3])) {
|
|
if (matches[4]) {
|
|
matches[4] = matches[4].padEnd(3, "00");
|
|
}
|
|
for (let j = 1, len = matches.length; j < len; j++) {
|
|
dateRet[j + 2] = +matches[j];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
matches = null;
|
|
if (match[4]) {
|
|
matches = TZ_REGEX.exec(match[4]);
|
|
if (matches) {
|
|
dateRet[7] = matches[1] ? NaN : +matches[2] * 60 + (matches[3] ? +matches[3] : 0);
|
|
}
|
|
}
|
|
return dateRet;
|
|
}
|
|
return input;
|
|
}
|
|
function createDate(y, m, d, h, minute, s, ms) {
|
|
let date;
|
|
if (y < 100 && y >= 0) {
|
|
date = new Date(y + 400, m, d, h, minute, s, ms);
|
|
if (isFinite(date.getFullYear())) {
|
|
date.setFullYear(y);
|
|
}
|
|
} else {
|
|
date = new Date(y, m, d, h, minute, s, ms);
|
|
}
|
|
return date;
|
|
}
|
|
function createUTCDate(y, m, d, h, minute, s, ms) {
|
|
let date;
|
|
if (y < 100 && y >= 0) {
|
|
y += 400;
|
|
date = new Date(Date.UTC(y, m, d, h, minute, s, ms));
|
|
if (isFinite(date.getUTCFullYear())) {
|
|
date.setUTCFullYear(y);
|
|
}
|
|
} else {
|
|
date = new Date(Date.UTC(y, m, d, h, minute, s, ms));
|
|
}
|
|
return date;
|
|
}
|
|
function createFromArray(input) {
|
|
const utcOffset = input[7];
|
|
const currentDate = /* @__PURE__ */ new Date();
|
|
const isUTC = Number.isNaN(utcOffset);
|
|
const flag = isUTC ? "UTC" : "";
|
|
const currentStuffing = [
|
|
currentDate[`get${flag}FullYear`](),
|
|
currentDate[`get${flag}Month`](),
|
|
currentDate[`get${flag}Date`]()
|
|
];
|
|
let i = 0;
|
|
const array = new Array(7);
|
|
for (; i < 3 && input[i] == null; ++i) {
|
|
array[i] = currentStuffing[i];
|
|
}
|
|
for (; i < 7; i++) {
|
|
array[i] = input[i] == null ? 0 : input[i];
|
|
}
|
|
let day = array[2];
|
|
if (day === 0) {
|
|
day = 1;
|
|
}
|
|
let minute = array[4];
|
|
if (!isUTC && typeof utcOffset === "number") {
|
|
minute -= utcOffset + currentDate.getTimezoneOffset();
|
|
}
|
|
return (isUTC ? createUTCDate : createDate)(
|
|
array[0],
|
|
array[1],
|
|
day,
|
|
array[3],
|
|
minute,
|
|
array[5],
|
|
array[6]
|
|
);
|
|
}
|
|
function toInteger(val) {
|
|
return parseInt(val, 10);
|
|
}
|
|
function toMonth(val) {
|
|
return parseInt(val, 10) - 1;
|
|
}
|
|
function toMilliseconds(val) {
|
|
return parseInt(val.padEnd(3, "0"), 10);
|
|
}
|
|
function parseTimezone(val) {
|
|
if (val === "Z") {
|
|
return NaN;
|
|
}
|
|
const matches = TZ_REGEX.exec(val);
|
|
return +matches[2] * 60 + (matches[3] ? +matches[3] : 0);
|
|
}
|
|
function extractWithFormat(input, format) {
|
|
const { pattern, tokens } = compile(format);
|
|
const match = new RegExp(pattern).exec(input);
|
|
if (!match) {
|
|
return "";
|
|
}
|
|
const parts = [];
|
|
tokens.forEach((token, i) => {
|
|
const value = match[i + 1];
|
|
switch (token) {
|
|
case "YYYY":
|
|
parts[0] = toInteger(value);
|
|
break;
|
|
// case 'YY':
|
|
// parts[0] = toInteger(value);
|
|
// break;
|
|
case "MM":
|
|
parts[1] = toMonth(value);
|
|
break;
|
|
case "DD":
|
|
parts[2] = toInteger(value);
|
|
break;
|
|
case "HH":
|
|
parts[3] = toInteger(value);
|
|
break;
|
|
case "mm":
|
|
parts[4] = toInteger(value);
|
|
break;
|
|
case "ss":
|
|
parts[5] = toInteger(value);
|
|
break;
|
|
case "SSS":
|
|
parts[6] = toMilliseconds(value);
|
|
break;
|
|
case "Z":
|
|
parts[7] = parseTimezone(value);
|
|
break;
|
|
}
|
|
});
|
|
return parts;
|
|
}
|
|
const { DATE, DAY, HOUR, MILLISECOND, MINUTE, MONTH, SECOND, YEAR, UTC_OFFSET } = units;
|
|
const ASP_NET_JSON_REGEX = /^\/?Date\((-?\d+)/i;
|
|
function ensureType(value, checked) {
|
|
return checked;
|
|
}
|
|
function parseObject(obj) {
|
|
const array = [];
|
|
Object.entries(obj).forEach(([unit, value]) => {
|
|
unit = normalizeUnit.normalizeUnit(unit);
|
|
switch (unit) {
|
|
case YEAR:
|
|
array[0] = value;
|
|
break;
|
|
case MONTH:
|
|
array[1] = value;
|
|
break;
|
|
case DATE:
|
|
case DAY:
|
|
array[2] = value;
|
|
break;
|
|
case HOUR:
|
|
array[3] = value;
|
|
break;
|
|
case MINUTE:
|
|
array[4] = value;
|
|
break;
|
|
case SECOND:
|
|
array[5] = value;
|
|
break;
|
|
case MILLISECOND:
|
|
array[6] = value;
|
|
break;
|
|
case UTC_OFFSET:
|
|
array[7] = value;
|
|
break;
|
|
}
|
|
});
|
|
if (array.length === 0) {
|
|
return /* @__PURE__ */ new Date();
|
|
}
|
|
return createFromArray(array);
|
|
}
|
|
function parseString(input, format) {
|
|
const extracted = typeof format === "string" && format ? extractWithFormat(input, format) : autoExtract(input);
|
|
if (Array.isArray(extracted)) {
|
|
return createFromArray(extracted);
|
|
}
|
|
const matched = ASP_NET_JSON_REGEX.exec(input);
|
|
return new Date(matched !== null ? +matched[1] : Date.parse(extracted));
|
|
}
|
|
function parse(input, format) {
|
|
let ret;
|
|
const whatType = typeof input;
|
|
if (ensureType(input, whatType === "string")) {
|
|
ret = parseString(input, format);
|
|
} else if (Array.isArray(input)) {
|
|
ret = createFromArray(input);
|
|
} else if (input instanceof Date) {
|
|
ret = new Date(input);
|
|
} else if (ensureType(input, whatType === "object" && input !== null)) {
|
|
if (input.isValid && input.isValid()) {
|
|
ret = /* @__PURE__ */ new Date(+input);
|
|
} else {
|
|
ret = parseObject(input);
|
|
}
|
|
} else if (ensureType(input, whatType === "number")) {
|
|
ret = new Date(input);
|
|
} else if (ensureType(input, whatType === "undefined")) {
|
|
ret = format ? /* @__PURE__ */ new Date(NaN) : /* @__PURE__ */ new Date();
|
|
} else {
|
|
ret = new Date(Date.parse(input));
|
|
}
|
|
return ret;
|
|
}
|
|
module.exports = parse;
|