Вы не можете подтвердить дату только с помощью регулярного выражения.Или, по крайней мере, не разумный.Для этого было бы достаточно продвинуться в високосные годы и т.д.В вашей функции oninput вы можете удалить нецифровые символы, работать со строкой цифр (убедитесь, что это правильная дата) и добавлять только другие символы («символы форматирования») туда, где они должны быть после этого.
Если у вас есть неполная дата в формате MMDDYYYY
(но возможно заполнение только некоторыми символами), и вы хотите убедиться, что это не может привести к недопустимой дате, у вас может быть функция, подобная приведенной ниже.
Одна хитрость заключается в том, что создание недопустимой даты в Javascript не всегда будет давать недопустимый результат, оно будет просто переполнено, поэтому 2019-01-32
даст вам дату для 2019-02-01
.Хотя это полезно в некоторых случаях, это раздражает нас, так как мы пытаемся обнаружить недопустимые даты.Но тогда мы можем убедиться, что строка, представляющая сгенерированную дату, совпадает с той, которую мы предоставили.Если это не так, мы находимся в случае «переполнения».
function hasErrors(val) {
let month = val.slice(0, 2);
let day = val.slice(2, 4);
let year = val.slice(4);
// The string is fully empty - not an invalid input
if (!month.length) {
return false;
}
// Only one of the months digits is filled out. Assume the rest will be filled out by the smallest possible valid value
// (optimistic heuristic)
if (month.length === 1) {
month += month === '0' ? '1' : '0';
}
// Invalid month
if (+month > 12 || +month <= 0) {
return true;
}
// Month valid but day not filled - ok
if (!day.length) {
return false;
}
// Only part of the day filled, same as above with the month
if (day.length === 1) {
day += day === '0' ? '1' : '0';
}
// Days always invalid
if (+day > 31 || +day <= 0) {
return true;
}
// If the year is not fully filled out, use any year with a 29 Feb
if (year.length < 4) {
year = '1972';
}
// Make sure the date is valid (e.g. no 31st of April)
let sourceStr = [year, month, day].join('-');
let date = new Date(sourceStr);
if (!+date || date.toISOString().slice(0, 10) !== sourceStr) {
return true;
}
// No error was detected
return false;
}
Вот пример скрипта .
Теперь, как уже упоминалось, UX-мудрыйдовольно плохая идея блокировать ввод пользователя.Это сбивает с толку, особенно при попытке отредактировать середину строки, а не конец.Лучшим решением было бы просто указать на ошибку с помощью стиля.Вот пример скрипта , не блокирующий пользовательский ввод (просто изменил деталь вокруг строки 76).