Merge pull request #15493 from calixteman/15490
[JS] Try to guess what the date is when it doesn't follow the given format (issue #15490)
This commit is contained in:
commit
9bdcdeef67
@ -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