web-ui-pack
Version:
Web package with UI elements
115 lines (114 loc) • 3.06 kB
JavaScript
import localeInfo from "../objects/localeInfo";
export default function dateFromString(v, format = "YYYY-MM-DD", options = { throwOutOfRange: true }) {
if (!v) {
return null;
}
format = format.replace(/MMM/, () => {
localeInfo.namesMonthShort.some((name, i) => {
let isFound = false;
v = v.replace(name, () => {
isFound = true;
return (i + 1).toString();
});
return isFound;
});
return "M";
});
let fLast = format.length - 1;
const isUTC = format.endsWith("Z") || format.endsWith("z");
fLast -= isUTC ? 1 : 0;
const h12 = format[fLast] === "a" || format[fLast] === "A";
let vLast = v.length - 1;
if (h12) {
fLast -= 1;
vLast -= 2;
}
const r = { y: 0, M: 0, d: 0, h: 0, m: 0, s: 0, f: 0 };
let vi = 0;
let yCnt = 0;
for (let fi = 0; vi <= vLast; ++vi, ++fi) {
let char = format[fi];
switch (char) {
case "Y":
char = "y";
break;
case "D":
char = "d";
break;
case "H":
char = "h";
break;
case "S":
char = "s";
break;
case "F":
char = "f";
break;
default: break;
}
const num = v.charCodeAt(vi) - 48;
const isNum = num >= 0 && num <= 9;
const key = char;
if (isNum) {
if (r[key] !== undefined) {
r[key] = r[key] * 10 + num;
if (key === "y") {
++yCnt;
}
}
else {
fi -= 2;
vi -= 1;
}
}
else if (char !== v[vi]) {
return null;
}
}
if (h12) {
const char = v[v.length - 2];
if (char === "P" || char === "p") {
r.h += r.h === 12 ? 0 : 12;
}
else if (char !== "A" && char !== "a") {
return null;
}
else if (r.h === 12) {
r.h = 0;
}
}
if (yCnt === 2) {
r.y += 2000;
}
--r.M;
let dt;
if (isUTC) {
dt = new Date(Date.UTC(r.y, r.M, r.d, r.h, r.m, r.s, r.f));
}
else {
dt = new Date(r.y, r.M, r.d, r.h, r.m, r.s, r.f);
}
const isOut = isOutOfRange(r, isUTC, dt);
if (isOut && options.throwOutOfRange) {
const err = RangeError("Out of range");
err.details = { format, raw: v, options, parsed: r };
console.warn(`${err.message}. Details:`, err.details);
throw err;
}
else if (isOut) {
return null;
}
return dt;
}
function isOutOfRange(r, isUTC, v) {
return (r.M < 0 ||
r.M > 11 ||
r.d < 1 ||
r.d > 31 ||
r.h > 23 ||
r.m > 59 ||
r.s > 59 ||
r.f > 999 ||
(v && r.M !== v[`get${isUTC ? "UTC" : ""}Month`]()) ||
false);
}