[JS] Try to guess what the date is when it doesn't follow the given format (issue #15490)
We use the format to guess in which order we can find month, day, ... we get the numbers in the date and consider them as month, day, ...
This commit is contained in:
parent
547fa3ed2c
commit
9e40938a29
@ -38,6 +38,7 @@ class AForm {
|
||||
"m/d/yy HH:MM",
|
||||
];
|
||||
this._timeFormats = ["HH:MM", "h:MM tt", "HH:MM:ss", "h:MM:ss tt"];
|
||||
this._dateActionsCache = new Map();
|
||||
|
||||
// The e-mail address regex below originates from:
|
||||
// https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
|
||||
@ -52,6 +53,93 @@ class AForm {
|
||||
return event.target ? `[ ${event.target.name} ]` : "";
|
||||
}
|
||||
|
||||
_tryToGuessDate(cFormat, cDate) {
|
||||
// We use the format to know the order of day, month, year, ...
|
||||
|
||||
let actions = this._dateActionsCache.get(cFormat);
|
||||
if (!actions) {
|
||||
actions = [];
|
||||
this._dateActionsCache.set(cFormat, actions);
|
||||
cFormat.replace(
|
||||
/(d+)|(m+)|(y+)|(H+)|(M+)|(s+)/g,
|
||||
function (match, d, m, y, H, M, s) {
|
||||
if (d) {
|
||||
actions.push((n, date) => {
|
||||
if (n >= 1 && n <= 31) {
|
||||
date.setDate(n);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
} else if (m) {
|
||||
actions.push((n, date) => {
|
||||
if (n >= 1 && n <= 12) {
|
||||
date.setMonth(n - 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
} else if (y) {
|
||||
actions.push((n, date) => {
|
||||
if (n < 50) {
|
||||
n += 2000;
|
||||
} else if (n < 100) {
|
||||
n += 1900;
|
||||
}
|
||||
date.setYear(n);
|
||||
return true;
|
||||
});
|
||||
} else if (H) {
|
||||
actions.push((n, date) => {
|
||||
if (n >= 0 && n <= 23) {
|
||||
date.setHours(n);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
} else if (M) {
|
||||
actions.push((n, date) => {
|
||||
if (n >= 0 && n <= 59) {
|
||||
date.setMinutes(n);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
} else if (s) {
|
||||
actions.push((n, date) => {
|
||||
if (n >= 0 && n <= 59) {
|
||||
date.setSeconds(n);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return "";
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const number = /\d+/g;
|
||||
let i = 0;
|
||||
let array;
|
||||
const date = new Date();
|
||||
while ((array = number.exec(cDate)) !== null) {
|
||||
if (i < actions.length) {
|
||||
if (!actions[i++](parseInt(array[0]), date)) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
_parseDate(cFormat, cDate) {
|
||||
let date = null;
|
||||
try {
|
||||
@ -60,7 +148,7 @@ class AForm {
|
||||
if (!date) {
|
||||
date = Date.parse(cDate);
|
||||
if (isNaN(date)) {
|
||||
date = null;
|
||||
date = this._tryToGuessDate(cFormat, cDate);
|
||||
} else {
|
||||
date = new Date(date);
|
||||
}
|
||||
|
@ -608,14 +608,23 @@ describe("Scripting", function () {
|
||||
it("should parse a date with a format", async () => {
|
||||
const check = async (date, format, expected) => {
|
||||
const value = await myeval(
|
||||
`AFParseDateEx("${date}", "${format}").toISOString()`
|
||||
`AFParseDateEx("${date}", "${format}").toISOString().replace(/T.*$/, "")`
|
||||
);
|
||||
expect(value).toEqual(
|
||||
new Date(expected).toISOString().replace(/T.*$/, "")
|
||||
);
|
||||
expect(value).toEqual(new Date(expected).toISOString());
|
||||
};
|
||||
|
||||
await check("05", "dd", "2000/01/05");
|
||||
await check("12", "mm", "2000/12/01");
|
||||
await check("2022", "yyyy", "2022/01/01");
|
||||
await check("a1$9bbbb21", "dd/mm/yyyy", "2021/09/01");
|
||||
|
||||
// The following test isn't working as expected because
|
||||
// the quickjs date parser has been replaced by the browser one
|
||||
// and the date "1.9.2021" is valid in Chrome but not in Firefox.
|
||||
// The supported date format is not specified...
|
||||
// await check("1.9.2021", "dd/mm/yyyy", "2021/09/01");
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user