UNPKG

date-manip

Version:

A lightweight JavaScript date utility library that provides modularity, high performance, and additional features. It supports various date operations, including date addition and subtraction, formatting, comparison, etc.

277 lines (276 loc) 7.32 kB
import compile from "./compile.mjs"; import { n as normalizeUnit } from "./normalizeUnit-bp5SODxw.mjs"; import units from "./units.mjs"; 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(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; } export { parse as default };