Проверить дату в JavaScript

Мне нужно выполнить проверку пользователем поля даты, оно должно быть в формате ггггММдд и не должно быть больше одного года в будущем. Как бы я это сделал? В настоящее время у меня есть только грубое регулярное выражение, которого недостаточно.

function VerifyDate(source, args)
{
    var regexp = /^([1-2]{1}[0-9]{1})\d{2}([0][1-9]|[1][0-2])([0][1-9]|[1-2][0-9]|[3][0-1])$/
    var result = args.Value.match(regexp);     
    if (result) {
        args.IsValid = true;
    } else {
        args.IsValid = false;
    }       
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 747
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Возьмите регулярное выражение только для проверки формата. Вы можете оставаться простым:

^(\d{4})(\d{2})(\d{2})$

Затем проанализируйте дату и проверьте диапазон:

function VerifyDate(source, args)
{
  args.IsValid = false;
  var regexp = /^(\d{4})(\d{2})(\d{2})$/;
  var daysInMonth = function (y, m) {return 32-new Date(y, m, 32).getDate(); };

  var ma = regexp.exec(args.Value);
  if (ma && ma.length == 4 && ma[2] < 12 && ma[3] <= daysInMonth(ma[1], ma[2]))
  {
    var diff = new Date(ma[1], ma[2], ma[3]) - new Date();
    args.IsValid = diff < 31536000000; // one year = 1000ms*60*60*24*365
  }
}

Приведенный выше код принимает 20019999, поскольку new Date () НЕ генерирует исключение в javascript, если месяц> 12 или день> daysInMonth (месяц).

some 19.01.2009 13:48

Ой. Я этого ожидал. Спасибо, учту.

Tomalak 19.01.2009 14:41

Близко, но все равно неверно ... Есть еще как минимум 2 ошибки: Одна из них - все даты в декабре считаются недействительными.

some 19.01.2009 15:41

new Date () не генерирует исключение, если месяц или день выходят за пределы допустимого диапазона. Он использует внутренний MakeDay для вычисления даты (см. Спецификация языка ECMAScript, разделы 15.9.3.1 и 15.9.1.13). Чтобы убедиться, что дата действительна в функции ниже, входные данные преобразуются в целые числа, которые преобразуются в дату, а затем части даты сравниваются с целыми числами.

Поскольку дата использует MakeDay, расчет maxDate работает, даже если сейчас - это выходной день (xxxx0229 будет yyyy0301, где yyyy = xxxx + 1)

function verifyDate(args)
{
    var result=false,
        match = args.Value.match(/^(\d{4})(\d{2})(\d{2})$/);
    if (match && match.length === 4)
    {
        var year = parseInt(match[1],10),
            month =parseInt(match[2],10) -1, // 0 = January
            day = parseInt(match[3],10),
            testDate= new Date(year,month,day),
            now = new Date(),
            maxDate = new Date(now.getFullYear() + 1, now.getMonth(), now. getDate()),
            minDate = new Date(1800,0,1),
            result = (
                 testDate.getFullYear() === year &&
                 testDate.getMonth() === month &&
                 testDate.getDate() === day &&
                 testDate >= minDate &&
                 testDate <= maxDate
            );
   }
   args.IsValue = result;
   return result;   
}

Решение, к которому я наконец пришел, представляет собой комбинацию ваших ответов, я использовал datejs, что кажется довольно приятным. Вот моя последняя функция проверки. По какой-то причине в месяце используется индекс, основанный на 0, поэтому в .set () указано -1.

function VerifyDate(source, args)
{
    args.IsValid = false;
    var regexp = /^(\d{4})(\d{2})(\d{2})$/;
    var m = regexp.exec(args.Value);
    if (m && m.length == 4) {
        try {
            var result = Date.today().set({ year: Number(m[1]), month: Number(m[2]-1), day: Number(m[3]) });
            if (result < Date.today().add({ years: 1 })) {
                args.IsValid = true;
            }
        }
        catch (ex) {
        }
    }
}

«Месяцы обозначаются целым числом в диапазоне от 0 до 11 включительно». см. раздел 15.9.1.4 в ecma-international.org/publications/files/ECMA-ST/Ecma-262.p‌ df

some 19.01.2009 15:49

Хорошо, я не знал этого до сегодняшнего дня и не видел спецификации ECMA. Но разве где-нибудь нет ссылки на javascript в более удобном для восприятия формате? Как веб-каталог? Копаться в pdf в лучшем случае обременительно.

zidar 19.01.2009 17:08

PDF-файл является авторитетным техническим ресурсом. Более удобный ресурс - w3schools.com/jsref/default.asp

some 19.01.2009 20:12

Другие вопросы по теме