Javascript: как проверить даты в формате ММ-ДД-ГГГГ?

Я увидел здесь потенциальный ответ, но он был для ГГГГ-ММ-ДД: Проверка даты JavaScript

Я изменил приведенный выше код для ММ-ДД-ГГГГ вот так, но все еще не могу заставить его работать:

String.prototype.isValidDate = function() 
{
     var IsoDateRe = new RegExp("^([0-9]{2})-([0-9]{2})-([0-9]{4})$");
     var matches = IsoDateRe.exec(this);
     if (!matches) return false;
     var composedDate = new Date(matches[3], (matches[1] - 1), matches[2]);
     return ((composedDate.getMonth() == (matches[1] - 1)) &&
      (composedDate.getDate() == matches[2]) &&
      (composedDate.getFullYear() == matches[3]));
}

Как я могу заставить приведенный выше код работать для ММ-ДД-ГГГГ, а еще лучше ММ / ДД / ГГГГ?

Спасибо.

См .: stackoverflow.com/a/15764763/1709992

Ore4444 02.04.2013 17:00

возможный дубликат Форматировать дату в формате ММ / дд / гггг в javascript

Sean Vieira 06.04.2013 18:30

или просто вы можете использовать это для проверки npmjs.com/package/raysk-vali

Ravi Singh 10.01.2020 18:10

См. Ответы дубликатов в stackoverflow.com/questions/6177975/…

Wolfgang Kuehn 25.03.2021 00:27
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
35
4
197 436
21

Ответы 21

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

var matches = this.match(/^([0-9]{2})/([0-9]{2})/([0-9]{4})$/);

Или просто измените параметр на конструктор RegExp, чтобы он был

^([0-9]{2})/([0-9]{2})/([0-9]{4})$

что с этим не работает? вот протестированная версия:

String.prototype.isValidDate = function()   {

    const match = this.match(/^([0-9]{2})/([0-9]{2})/([0-9]{4})$/);
    if (!match || match.length !== 4) {
        return false
    }

    const test = new Date(match[3], match[1] - 1, match[2]);

    return (
        (test.getMonth() == match[1] - 1) &&
        (test.getDate() == match[2]) &&
        (test.getFullYear() == match[3])
    );
}

var date = '12/08/1984'; // Date() is 'Sat Dec 08 1984 00:00:00 GMT-0800 (PST)'
alert(date.isValidDate() ); // true

что, если совпадений не найдено, тогда новая дата (совпадение [3], совпадение [1] - 1, совпадение [2]); не будет работать - обновить: исправлено

Roel 18.12.2020 17:49

Я использую это регулярное выражение для проверки ММ-ДД-ГГГГ:

function isValidDate(subject){
  if (subject.match(/^(?:(0[1-9]|1[012])[\- /.](0[1-9]|[12][0-9]|3[01])[\- /.](19|20)[0-9]{2})$/)){
    return true;
  }else{
    return false;
  }
}

Он будет соответствовать только действительным месяцам, и вы можете использовать / - или. как разделители.

он вернет 29.02.2011 как истину, но должен вернуть ложь

bugwheels94 28.07.2012 15:16

Согласно вашей функции «02-29-2011» - допустимая дата, и даже «02-30-2011», «02 -31-2011» - допустимые даты.

Marco Demaio 25.02.2014 21:53
function isValidDate(date)
{
    var matches = /^(\d{1,2})[-/](\d{1,2})[-/](\d{4})$/.exec(date);
    if (matches == null) return false;
    var d = matches[2];
    var m = matches[1] - 1;
    var y = matches[3];
    var composedDate = new Date(y, m, d);
    return composedDate.getDate() == d &&
            composedDate.getMonth() == m &&
            composedDate.getFullYear() == y;
}
console.info(isValidDate('10-12-1961'));
console.info(isValidDate('12/11/1961'));
console.info(isValidDate('02-11-1961'));
console.info(isValidDate('12/01/1961'));
console.info(isValidDate('13-11-1961'));
console.info(isValidDate('11-31-1961'));
console.info(isValidDate('11-31-1061'));

Оно работает. (Протестировано с помощью Firebug, отсюда и console.info ().)

@ChristianVielma Правда? Вы пробовали код? В каком браузере?

PhiLho 28.03.2013 13:22

Нет, ты прав, просто проверил еще раз, и все хорошо. Прости за это!

Christian Vielma 28.03.2013 17:53

Однако это не сработает, если вы используете только одну цифру для месяца. Например, «1-31-2013» не удастся. Кроме того, одна цифра для дня "01 -1-2013" или, если вы используете две цифры для года "01 -01-13"

Icemanind 18.06.2013 12:43

используйте это регулярное выражение, чтобы принимать однозначные значения дня и месяца. / ^ (\ d {1,2}) [- \ /] (\ d {1,2}) [- \ /] (\ d {4}) $ /

Orchid 26.06.2014 16:06

@AnilNamde отредактировал мой ответ, чтобы принять 1-значный день или месяц. Я не буду редактировать его обратно, так как он может быть полезен (судя по комментариям выше), но изначально это не то, о чем просили ...

PhiLho 26.06.2016 19:31

Как насчет проверки дат в "ЛЮБОМ" формате даты? Я использую библиотеку DateJS и добавляю ее к существующим формам, чтобы убедиться, что я получаю действительные даты и время, отформатированные так, как я хочу. Пользователь может даже ввести такие вещи, как «сейчас» и «завтра», и это будет преобразовано в действительную дату.

Вот библиотека dateJS: http://www.datejs.com/

и вот совет jQuery, который я написал: http://www.ssmedia.com/utilities/jquery/index.cfm/datejs.htm

function isValidDate(date) {
        var valid = true;

        date = date.replace('/-/g', '');

        var month = parseInt(date.substring(0, 2),10);
        var day   = parseInt(date.substring(2, 4),10);
        var year  = parseInt(date.substring(4, 8),10);

        if (isNaN(month) || isNaN(day) || isNaN(year)) return false;

        if ((month < 1) || (month > 12)) valid = false;
        else if ((day < 1) || (day > 31)) valid = false;
        else if (((month == 4) || (month == 6) || (month == 9) || (month == 11)) && (day > 30)) valid = false;
        else if ((month == 2) && (((year % 400) == 0) || ((year % 4) == 0)) && ((year % 100) != 0) && (day > 29)) valid = false;
        else if ((month == 2) && ((year % 100) == 0) && (day > 29)) valid = false;
        else if ((month == 2) && (day > 28)) valid = false;

    return valid;
}

Это проверяет действительные дни в каждом месяце и действительные дни високосного года.

К вашему сведению, вам нужно исправить второй и четвертый elseIf. # 2 Удалите (месяц == 7), потому что в июле 31 день. # 4 Изменение ((год% 100) == 0) || (день> 28)) до ((год% 100) == 0) && (день> 28)). Это указывает на то, что должны быть выполнены все три условия. В противном случае функция вернет false, если Day> 28, независимо от того, високосный год это или нет. В любом случае, вы получите +1, потому что это мне очень помогло.

Saahir Foux 21.07.2012 02:53

Fyi, для будущих читателей вы ДОЛЖНЫ также применить к своему коду следующее, чтобы все вышесказанное работало правильно. Измените date.replace, показанный выше, на date.replace (/ - / g, '') ", чтобы убедиться, что он заменяет все дефисы, а не только первый. Кроме того, вы столкнетесь с причудой дизайна 1: 1000000 в parseInt с вашей переменной дня, если date.substring (2,4) имеет значение '08' или '09. См. Следующую ссылку для получения подробной информации и решения. support.microsoft.com/kb/191434

Saahir Foux 21.07.2012 10:19

если я не ошибаюсь, это надо писать без '. дата = date.replace (/ - / g, ''); В противном случае он будет искать строку типа «/ - / g».

sataniccrow 02.04.2014 11:43

и я на 100% уверен, что в вашем коде високосного года есть ошибки (он подтверждает, что это правда даже для такой даты, как эта 29.02.2001)

sataniccrow 04.04.2014 12:23

@sataniccrow теперь исправлено

Виталий Олегович 17.12.2015 19:30

@VitalijZadneprovskij, если я указываю дату ввода как «abc» или «123», она дает истину. Я думаю, что эта проверка не полностью завершена.

SkyWalker 13.04.2016 11:48

передать эту функцию в дату с форматом // 10-10-2012 и идентификатором объекта.

function isValidDateFormat(date, id)
{
  var todayDate = new Date();
  var matches = /^(\d{2})[-/](\d{2})[-/](\d{4})$/.exec(date);

  if (matches == null)
  {
   if (date != '__-__-____')
    {
      alert('Please enter valid date');
    }
  }
  else
  {
    var day    = 31;
    var month  = 12;
    var b_date = date.split("-");
    if (b_date[0] <= day)
    {
      if (b_date[1] <= month)
      {
        if (b_date[2] >= 1900 && b_date[2] <= todayDate.getFullYear())
        {
          return true;
        }
        else
        {
          $("#"+id).val('');
          alert('Please enter valid Year'); 
        }         
      }
      else
      {
        $("#"+id).val('');
        alert('Please enter valid Month');    
      } 
    }
    else
    {
      alert('Please enter valid Day');
      $("#"+id).val('');  
    }
  }
}

Вы можете объяснить, зачем здесь нужен jQuery?

Nico Haase 01.03.2019 16:40

Простой способ решить

var day = document.getElementById("DayTextBox").value;

var regExp = /^([1-9]|[1][012])/|-([1-9]|[1][0-9]|[2][0-9]|[3][01])/|-([1][6-9][0-9][0-9]|[2][0][01][0-9])$/;

return regExp.test(day);

Согласно вашему коду '02 -29-2011 'является допустимой датой, и даже '02-30-2011', '02 -31-2011 'являются допустимыми датами.

Marco Demaio 25.02.2014 21:52

Это необходимо для проверки строки даты в формате dd.mm.yyyy. Его легко настроить. Вам просто нужно настроить pos1 и pos2 в isValidDate ().

var dtCh = "."; var minYear = 1900;

function isInteger(s){
    var i;
    for (i = 0; i < s.length; i++){   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(s, bag){
    var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
    // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
    for (var i = 1; i <= n; i++) {
        this[i] = 31;
        if (i==4 || i==6 || i==9 || i==11) {
            this[i] = 30;
        }
        if (i==2) {
            this[i] = 29;
        }
   } 
   return this;
}

function isValidDate(dtStr){
    var daysInMonth = DaysArray(12);
    var pos1=dtStr.indexOf(dtCh);
    var pos2=dtStr.indexOf(dtCh,pos1+1);
    var strDay=dtStr.substring(0,pos1);
    var strMonth=dtStr.substring(pos1+1,pos2);
    var strYear=dtStr.substring(pos2+1);
    strYr=strYear;
    if (strDay.charAt(0)= = "0" && strDay.length>1) 
        strDay=strDay.substring(1);
    if (strMonth.charAt(0)= = "0" && strMonth.length>1) 
        strMonth=strMonth.substring(1);
    for (var i = 1; i <= 3; i++) {
        if (strYr.charAt(0)= = "0" && strYr.length>1) 
            strYr=strYr.substring(1);
    }
    month=parseInt(strMonth);
    day=parseInt(strDay);
    year=parseInt(strYr);
    if (pos1==-1 || pos2==-1){
        alert("The date format should be : dd.mm.yyyy");
        return false;
    }
    if (strMonth.length<1 || month<1 || month>12){
        alert("Please enter a valid month");
        return false;
    }
    if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
        alert("Please enter a valid day");
        return false;
    }
    if (strYear.length != 4 || year==0 || year<minYear){
        alert("Please enter a valid 4 digit year after "+minYear);
        return false;
    }
    if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
        alert("Please enter a valid date");
        return false;
    }
    return true;
}
<script language = "Javascript">
// Declaring valid date character, minimum year and maximum year
var dtCh= "/";
var minYear=1900;
var maxYear=2100;

function isInteger(s){
    var i;
    for (i = 0; i < s.length; i++){   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(s, bag){
    var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
    // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
    for (var i = 1; i <= n; i++) {
        this[i] = 31
        if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
        if (i==2) {this[i] = 29}
   } 
   return this
}

function isDate(dtStr){
    var daysInMonth = DaysArray(12)
    var pos1=dtStr.indexOf(dtCh)
    var pos2=dtStr.indexOf(dtCh,pos1+1)
    var strDay=dtStr.substring(0,pos1)
    var strMonth=dtStr.substring(pos1+1,pos2)
    var strYear=dtStr.substring(pos2+1)
    strYr=strYear
    if (strDay.charAt(0)= = "0" && strDay.length>1) strDay=strDay.substring(1)
    if (strMonth.charAt(0)= = "0" && strMonth.length>1) strMonth=strMonth.substring(1)
    for (var i = 1; i <= 3; i++) {
        if (strYr.charAt(0)= = "0" && strYr.length>1) strYr=strYr.substring(1)
    }
    month=parseInt(strMonth)
    day=parseInt(strDay)
    year=parseInt(strYr)
    if (pos1==-1 || pos2==-1){
        alert("The date format should be : dd/mm/yyyy")
        return false
    }
    if (strMonth.length<1 || month<1 || month>12){
        alert("Please enter a valid month")
        return false
    }
    if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
        alert("Please enter a valid day")
        return false
    }
    if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
        alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear)
        return false
    }
    if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
        alert("Please enter a valid date")
        return false
    }
return true
}

function ValidateForm(){
    var dt=document.frmSample.txtDateenter code here
    if (isDate(dt.value)==false){
        dt.focus()
        return false
    }
    return true
 }

</script>

Эта функция проверит дату, чтобы увидеть, верна ли она или имеет ли она правильный формат: ДД / ММ / ГГГГ.

function isValidDate(date)
{
    var matches = /^(\d{2})[-/](\d{2})[-/](\d{4})$/.exec(date);
    if (matches == null) return false;
    var d = matches[1];
    var m = matches[2]-1;
    var y = matches[3];
    var composedDate = new Date(y, m, d);
    return composedDate.getDate() == d &&
           composedDate.getMonth() == m &&
           composedDate.getFullYear() == y;
}
console.info(isValidDate('10-12-1961'));
console.info(isValidDate('12/11/1961'));
console.info(isValidDate('02-11-1961'));
console.info(isValidDate('12/01/1961'));
console.info(isValidDate('13-11-1961'));
console.info(isValidDate('11-31-1961'));
console.info(isValidDate('11-31-1061'));

Я бы использовал для этой задачи Moment.js. Это делает его очень просто для синтаксического анализа дат, а также обеспечивает поддержку для обнаружения недопустимого date1 в правильном формате. Например, рассмотрим этот пример:

var formats = ['MM-DD-YYYY', 'MM/DD/YYYY']

moment('11/28/1981', formats).isValid()  // true
moment('2-29-2003', formats).isValid()   // false (not leap year)
moment('2-29-2004', formats).isValid()   // true  (leap year)

Сначала moment(.., formats) используется для анализа ввода в соответствии с предоставленным локализованным форматом. Затем для полученного объекта момента вызывается функция isValid, чтобы мы действительно могли определить, является ли это датой действительный.

Это можно использовать для простого получения метода isValidDate:

String.prototype.isValidDate = function() {
    var formats = ['MM-DD-YYYY', 'MM/DD/YYYY'];
    return moment("" + this, formats).isValid();
}

1 Поскольку я не могу найти немного комментариев по этому поводу, я бы использовал moment.js только для дат, охватываемых Григорианский календарь. Могут быть плагины для других (в том числе исторических или научных) календарей.

if (document.getElementById('expiryDay').value != test(match("/^([0-9]{2})/([0-9]{2})$/"))){
     alert("Enter the date in two digit month flowed by two digits year \n");
}
<!DOCTYPE html>  
<html>  
<head>  

<title></title>  
 <script>
     function dateCheck(inputText) {
         debugger;

         var dateFormat = /^(0?[1-9]|[12][0-9]|3[01])[/\-](0?[1-9]|1[012])[/\-]\d{4}$/;

         var flag = 1;

         if (inputText.value.match(dateFormat)) {
             document.myForm.dateInput.focus();

             var inputFormat1 = inputText.value.split('/');
             var inputFormat2 = inputText.value.split('-');
             linputFormat1 = inputFormat1.length;
             linputFormat2 = inputFormat2.length;

             if (linputFormat1 > 1) {
                 var pdate = inputText.value.split('/');
             }
             else if (linputFormat2 > 1) {
                 var pdate = inputText.value.split('-');
             }
             var date = parseInt(pdate[0]);
             var month = parseInt(pdate[1]);
             var year = parseInt(pdate[2]);

             var ListofDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
             if (month == 1 || month > 2) {
                 if (date > ListofDays[month - 1]) {
                     alert("Invalid date format!");
                     return false;
                 }
             }

             if (month == 2) {
                 var leapYear = false;

                 if ((!(year % 4) && year % 100) || !(year % 400)) {
                     leapYear = true;

                 }
                 if ((leapYear == false) && (date >= 29)) {
                     alert("Invalid date format!");
                     return false;
                 }
                 if ((leapYear == true) && (date > 29)) {
                     alert("Invalid date format!");
                     return false;
                 }
             }
             if (flag == 1) {
                 alert("Valid Date");
             }
         }
         else {
             alert("Invalid date format!");
             document.myForm.dateInput.focus();
             return false;
         }
     }
     function restrictCharacters(evt) {

         evt = (evt) ? evt : window.event;
         var charCode = (evt.which) ? evt.which : evt.keyCode;
         if (((charCode >= '48') && (charCode <= '57')) || (charCode == '47')) {
             return true;
         }
         else {
             return false;
         }
     }


 </script>   
</head>



<body>  
    <div>  
        <form name = "myForm" action = "#">   
            <table>
                <tr>
                    <td>Enter Date</td>
                    <td><input type = "text" onkeypress = "return restrictCharacters(event);" name = "dateInput"/></td>
                    <td></td>
                    <td><span id = "span2"></span></td>
                </tr>

                <tr>
                    <td></td>
                    <td><input type = "button" name = "submit" value = "Submit" onclick = "dateCheck(document.myForm.dateInput)"  /></td>
                </tr>
            </table>
        </form>  
    </div>   
</body>  
</html> 

Пожалуйста, найдите в приведенном ниже коде, который позволяет выполнять проверку даты для любого из предоставленных форматов или на основе локали пользователя для проверки дат начала / от и окончания / до. Могут быть какие-то лучшие подходы, но они придумали это. Протестировали его для следующих форматов: MM / dd / yyyy, dd / MM / yyyy, yyyy-MM-dd, yyyy.MM.dd, yyyy / MM / dd и dd-MM-yyyy.

Обратите внимание, что предоставленный формат даты и строка даты идут рука об руку.

<script type = "text/javascript">
function validate(format) {

    if (isAfterCurrentDate(document.getElementById('start').value, format)) {
        alert('Date is after the current date.');
    } else {
        alert('Date is not after the current date.');
    }
    if (isBeforeCurrentDate(document.getElementById('start').value, format)) {
        alert('Date is before current date.');
    } else {
        alert('Date is not before current date.');
    }
    if (isCurrentDate(document.getElementById('start').value, format)) {
        alert('Date is current date.');
    } else {
        alert('Date is not a current date.');
    }
    if (isBefore(document.getElementById('start').value, document.getElementById('end').value, format)) {
        alert('Start/Effective Date cannot be greater than End/Expiration Date');
    } else {
        alert('Valid dates...');
    }
    if (isAfter(document.getElementById('start').value, document.getElementById('end').value, format)) {
        alert('End/Expiration Date cannot be less than Start/Effective Date');
    } else {
        alert('Valid dates...');
    }
    if (isEquals(document.getElementById('start').value, document.getElementById('end').value, format)) {
        alert('Dates are equals...');
    } else {
        alert('Dates are not equals...');
    }
    if (isDate(document.getElementById('start').value, format)) {
        alert('Is valid date...');
    } else {
        alert('Is invalid date...');
    }
}

/**
 * This method gets the year index from the supplied format
 */
function getYearIndex(format) {

    var tokens = splitDateFormat(format);

    if (tokens[0] === 'YYYY'
            || tokens[0] === 'yyyy') {
        return 0;
    } else if (tokens[1]=== 'YYYY'
            || tokens[1] === 'yyyy') {
        return 1;
    } else if (tokens[2] === 'YYYY'
            || tokens[2] === 'yyyy') {
        return 2;
    }
    // Returning the default value as -1
    return -1;
}

/**
 * This method returns the year string located at the supplied index
 */
function getYear(date, index) {

    var tokens = splitDateFormat(date);
    return tokens[index];
}

/**
 * This method gets the month index from the supplied format
 */
function getMonthIndex(format) {

    var tokens = splitDateFormat(format);

    if (tokens[0] === 'MM'
            || tokens[0] === 'mm') {
        return 0;
    } else if (tokens[1] === 'MM'
            || tokens[1] === 'mm') {
        return 1;
    } else if (tokens[2] === 'MM'
            || tokens[2] === 'mm') {
        return 2;
    }
    // Returning the default value as -1
    return -1;
}

/**
 * This method returns the month string located at the supplied index
 */
function getMonth(date, index) {

    var tokens = splitDateFormat(date);
    return tokens[index];
}

/**
 * This method gets the date index from the supplied format
 */
function getDateIndex(format) {

    var tokens = splitDateFormat(format);

    if (tokens[0] === 'DD'
            || tokens[0] === 'dd') {
        return 0;
    } else if (tokens[1] === 'DD'
            || tokens[1] === 'dd') {
        return 1;
    } else if (tokens[2] === 'DD'
            || tokens[2] === 'dd') {
        return 2;
    }
    // Returning the default value as -1
    return -1;
}

/**
 * This method returns the date string located at the supplied index
 */
function getDate(date, index) {

    var tokens = splitDateFormat(date);
    return tokens[index];
}

/**
 * This method returns true if date1 is before date2 else return false
 */
function isBefore(date1, date2, format) {
    // Validating if date1 date is greater than the date2 date
    if (new Date(getYear(date1, getYearIndex(format)), 
            getMonth(date1, getMonthIndex(format)) - 1, 
            getDate(date1, getDateIndex(format))).getTime()
        > new Date(getYear(date2, getYearIndex(format)), 
            getMonth(date2, getMonthIndex(format)) - 1, 
            getDate(date2, getDateIndex(format))).getTime()) {
        return true;
    } 
    return false;                
}

/**
 * This method returns true if date1 is after date2 else return false
 */
function isAfter(date1, date2, format) {
    // Validating if date2 date is less than the date1 date
    if (new Date(getYear(date2, getYearIndex(format)), 
            getMonth(date2, getMonthIndex(format)) - 1, 
            getDate(date2, getDateIndex(format))).getTime()
        < new Date(getYear(date1, getYearIndex(format)), 
            getMonth(date1, getMonthIndex(format)) - 1, 
            getDate(date1, getDateIndex(format))).getTime()
        ) {
        return true;
    } 
    return false;                
}

/**
 * This method returns true if date1 is equals to date2 else return false
 */
function isEquals(date1, date2, format) {
    // Validating if date1 date is equals to the date2 date
    if (new Date(getYear(date1, getYearIndex(format)), 
            getMonth(date1, getMonthIndex(format)) - 1, 
            getDate(date1, getDateIndex(format))).getTime()
        === new Date(getYear(date2, getYearIndex(format)), 
            getMonth(date2, getMonthIndex(format)) - 1, 
            getDate(date2, getDateIndex(format))).getTime()) {
        return true;
    } 
    return false;
}

/**
 * This method validates and returns true if the supplied date is 
 * equals to the current date.
 */
function isCurrentDate(date, format) {
    // Validating if the supplied date is the current date
    if (new Date(getYear(date, getYearIndex(format)), 
            getMonth(date, getMonthIndex(format)) - 1, 
            getDate(date, getDateIndex(format))).getTime()
        === new Date(new Date().getFullYear(), 
                new Date().getMonth(), 
                new Date().getDate()).getTime()) {
        return true;
    } 
    return false;                
}

/**
 * This method validates and returns true if the supplied date value 
 * is before the current date.
 */
function isBeforeCurrentDate(date, format) {
    // Validating if the supplied date is before the current date
    if (new Date(getYear(date, getYearIndex(format)), 
            getMonth(date, getMonthIndex(format)) - 1, 
            getDate(date, getDateIndex(format))).getTime()
        < new Date(new Date().getFullYear(), 
                new Date().getMonth(), 
                new Date().getDate()).getTime()) {
        return true;
    } 
    return false;                
}

/**
 * This method validates and returns true if the supplied date value 
 * is after the current date.
 */
function isAfterCurrentDate(date, format) {
    // Validating if the supplied date is before the current date
    if (new Date(getYear(date, getYearIndex(format)), 
            getMonth(date, getMonthIndex(format)) - 1, 
            getDate(date, getDateIndex(format))).getTime()
        > new Date(new Date().getFullYear(),
                new Date().getMonth(), 
                new Date().getDate()).getTime()) {
        return true;
    } 
    return false;                
}

/**
 * This method splits the supplied date OR format based 
 * on non alpha numeric characters in the supplied string.
 */
function splitDateFormat(dateFormat) {
    // Spliting the supplied string based on non characters
    return dateFormat.split(/\W/);
}

/*
 * This method validates if the supplied value is a valid date.
 */
function isDate(date, format) {                
    // Validating if the supplied date string is valid and not a NaN (Not a Number)
    if (!isNaN(new Date(getYear(date, getYearIndex(format)), 
            getMonth(date, getMonthIndex(format)) - 1, 
            getDate(date, getDateIndex(format))))) {                    
        return true;
    } 
    return false;                                      
}

Below is the HTML snippet

    <input type = "text" name = "start" id = "start" size = "10" value = "05/31/2016" />
<br/> 
<input type = "text" name = "end" id = "end" size = "10" value = "04/28/2016" />
<br/>
<input type = "button" value = "Submit" onclick = "javascript:validate('MM/dd/yyyy');" />

Если ваша дата должна соответствовать DD.MM.YYYY и использовать AngularJS, используйте следующий код:

$scope.validDate = function(value){
            var matches = /^(\d{1,2})[.](\d{1,2})[.](\d{4})$/.exec(value);
            if (matches == null) return false;
            var d = matches[1];
            var m = matches[2] - 1;
            var y = matches[3];
            var composedDate = new Date(y, m, d);
            return composedDate.getDate() == d &&
                composedDate.getMonth() == m &&
                composedDate.getFullYear() == y;
        };
            console.info($scope.validDate('22.04.2001'));
            console.info($scope.validDate('03.10.2001'));
            console.info($scope.validDate('30.02.2001'));
            console.info($scope.validDate('23.09.2016'));
            console.info($scope.validDate('29.02.2016'));
            console.info($scope.validDate('31.02.2016'));

Подробнее об объекте области можно узнать здесь. Без AngularJS просто измените первую строку на:

ValidDate = new function(value) {

И назовите это, используя:

var MyDate= ValidDate('29.09.2016');

Это не ответ на исходный вопрос, но я вижу, что вопрос изменился на какую-то статью из базы знаний для JS и дат. Не могли бы вы добавить некоторую информацию об объекте $scope, насколько я знаю, это не стандартный объект и может создать ошибку ссылки на объект.

SaschaM78 23.09.2016 10:17

Я использовал это решение в своем проекте AngularJs. $ Scope связь - это объект, который ссылается на модель приложения. Если вы вставите этот код в проект без AngularJs, вам придется удалить объект $ scope, чтобы он заработал.

Dominik Baran 29.09.2016 11:37

Спасибо за пояснение, теперь ответ для меня имеет смысл.

SaschaM78 29.09.2016 12:05

DateFormat = DD.MM.YYYY или D.M.YYYY

function dateValidate(val){ 
var dateStr = val.split('.'); 
  var date = new Date(dateStr[2], dateStr[1]-1, dateStr[0]); 
  if (date.getDate() == dateStr[0] && date.getMonth()+1 == dateStr[1] && date.getFullYear() == dateStr[2])
  { return date; }
  else{ return 'NotValid';} 
}

попробуй это:

function validateDate(dates){
    re = /^(\d{1,2})/(\d{1,2})/(\d{4})$/;     
    var days=new Array(31,28,31,30,31,30,31,31,30,31,30,31);

            if (regs = dates.match(re)) {
                    // day value between 1 and 31
                    if (regs[1] < 1 || regs[1] > 31) {                    
                      return false;
                    }
                    // month value between 1 and 12
                    if (regs[2] < 1 || regs[2] > 12) {                         
                      return false;
                    }

                    var maxday=days[regs[2]-1];

                    if (regs[2]==2){
                        if (regs[3]%4==0){
                            maxday=maxday+1;                                
                        }
                    }

                    if (regs[1]>maxday){
                        return false;
                    }

                    return true;
              }else{
                  return false;
              }                   
}

Коротко и быстро.

function dateValid(date) {
  var match = date.match(/^(\d\d)-(\d\d)-(\d{4})$/) || [];
  var m = (match[1] | 0) - 1;
  var d = match[2] | 0;
  var y = match[3] | 0;
  return !(
      m < 0 ||                     // Before January
      m > 11 ||                    // After December
      d < 1 ||                     // Before the 1st of the month
      d - 30 > (2773 >> m & 1) ||  // After the 30th or 31st of the month using bitmap
      m == 1 && d - 28 >           // After the 28th or 29th of February depending on leap year
          (!(y % 4) && y % 100 || !(y % 400)));
}

console.info('02-29-2000', dateValid('02-29-2000'));
console.info('02-29-2001', dateValid('02-29-2001'));
console.info('12-31-1970', dateValid('12-31-1970'));
console.info('Hello', dateValid('Hello'));

Пожалуйста, добавьте пояснения к вашему коду, чтобы другие могли извлечь из него уроки - например, что это за часть с 2741?

Nico Haase 01.03.2019 16:39

@NicoHaase добавил несколько комментариев к коду. 2741 - это битовая карта, где 1 означает, что в месяце 31 день, 0 означает иное.

Adam Leggett 04.03.2019 18:46

@AdamLeggett Замена (!(y % 4) && y % 100 || !(y % 400))) на !(y%4 || (!(y%100) && y%400)) ) исправляет ошибку, обнаруженную при тестировании с не тысячелетними високосными годами - выражение y % 100 не преобразуется в логическое значение, поэтому оно не приводится к 1 при численном сравнении.

traktor 31.10.2020 05:34

Немецкий вариант, но может быть адаптирован к ISO

export function isLeapYear(year) {
  return (
    year % 4 === 0 && (year % 100 != 0 || year % 1000 === 0 || year % 400 === 0)
  )
}

export function isValidGermanDate(germanDate) {
  if (
    !germanDate ||
    germanDate.length < 5 ||
    germanDate.split('.').length < 3
  ) {
    return false
  }

  const day = parseInt(germanDate.split('.')[0])
  const month = parseInt(germanDate.split('.')[1])
  const year = parseInt(germanDate.split('.')[2])

  if (isNaN(month) || isNaN(day) || isNaN(year)) {
    return false
  }

  if (month < 1 || month > 12) {
    return false
  }

  if (day < 1 || day > 31) {
    return false
  }

  if ((month === 4 || month === 6 || month === 9 || month === 11) && day > 30) {
    return false
  }

  if (isLeapYear(year)) {
    if (month === 2 && day > 29) {
      return false
    }
  } else {
    if (month === 2 && day > 28) {
      return false
    }
  }

  return true
}

Расширяя "Коротко и быстро" выше @Adam Leggett, так как случаи, подобные "30.02.2020", возвращают true, тогда как это должно быть false. Я действительно копаю растровое изображение ...

Для проверки формата даты ММ / ДД / ГГГГ:

const dateValid = (date) => {
  const isLeapYear = (yearNum) => {
    return ((yearNum % 100 === 0) ? (yearNum % 400 === 0) : (yearNum % 4 === 0))?
      1:
      0;
  }
  const match = date.match(/^(\d\d)/(\d\d)/(\d{4})$/) || [];
  const month = (match[1] | 0) - 1;
  const day = match[2] | 0;
  const year = match[3] | 0;

const dateEval=!( month < 0 ||                     // Before January
      month > 11 ||                    // After December
      day < 1 ||                     // Before the 1st of the month
      day - 30 > (2773 >> month & 1) ||
      month === 1 && day - 28 > isLeapYear(year) 
      // Day is 28 or 29, month is 02, year is leap year ==> true
      );

return `\nDate: ${date}\n\n     
  Valid Date?: ${dateEval}\n
  =======================================`
}

console.info(dateValid('02/28/2020')) // true
console.info(dateValid('02/29/2020')) // true
console.info(dateValid('02/30/2020')) // false
console.info(dateValid('01/31/2020')) // true
console.info(dateValid('01/31/2000')) // true
console.info(dateValid('04/31/2020')) // false
console.info(dateValid('04/31/2000')) // false
console.info(dateValid('04/30/2020')) // true
console.info(dateValid('01/32/2020')) // false
console.info(dateValid('02/28/2021')) // true
console.info(dateValid('02/29/2021')) // false
console.info(dateValid('02/30/2021')) // false
console.info(dateValid('02/28/2000')) // true
console.info(dateValid('02/29/2000')) // true
console.info(dateValid('02/30/2000')) // false
console.info(dateValid('02/28/2001')) // true
console.info(dateValid('02/29/2001')) // false
console.info(dateValid('02/30/2001')) // false

Для проверки формата даты ММ-ДД-ГГГГ: замените / в шаблоне для match на -.

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