36

I saw a potential answer here but that was for YYYY-MM-DD: JavaScript date validation

I modified the code code above for MM-DD-YYYY like so but I still can't get it to work:

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]));
}

How can I get the above code to work for MM-DD-YYYY and better yet MM/DD/YYYY?

Thanks.

706Astor
  • 285
  • 2
  • 10
Sajee
  • 4,317
  • 14
  • 46
  • 54

21 Answers21

80
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.log(isValidDate('10-12-1961'));
console.log(isValidDate('12/11/1961'));
console.log(isValidDate('02-11-1961'));
console.log(isValidDate('12/01/1961'));
console.log(isValidDate('13-11-1961'));
console.log(isValidDate('11-31-1961'));
console.log(isValidDate('11-31-1061'));

It works. (Tested with Firebug, hence the console.log().)

Anil Namde
  • 6,452
  • 11
  • 63
  • 100
PhiLho
  • 40,535
  • 6
  • 96
  • 134
  • 5
    @ChristianVielma Really? Have you tried the code? On which browser? – PhiLho Mar 28 '13 at 09:22
  • Nop, you're right, just tested it again and it is good. Sorry about that! – Christian Vielma Mar 28 '13 at 13:53
  • It does fail though if you use only one digit for the month. For example, '1-31-2013' will fail. Also, one digit for the day '01-1-2013' or if you use two digits for the year '01-01-13' – Icemanind Jun 18 '13 at 08:43
  • 1
    use this regular expression to accept one digit day and month values. /^(\d{1,2})[-\/](\d{1,2})[-\/](\d{4})$/ – Orchid Jun 26 '14 at 12:06
  • @AnilNamde edited my answer to accept 1 digit day or month. I won't edit it back as it might have its use (judging by comments above), but that's not what was asked originally... – PhiLho Jun 26 '16 at 16:31
13
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;
}

This checks for valid days in each month and for valid leap year days.

Matthew Carroll
  • 433
  • 5
  • 16
  • 1
    FYI, you need to correct your second and fourth elseIf. #2 Remove (month ==7) because July does have 31 days. #4 Change ((year % 100) == 0) || (day > 28)) to ((year % 100) == 0) && (day > 28)). This specifies all three conditions must be met. Otherwise the func will return false if Day > 28 regardless if its a leap year or not. Anyway, you get a +1 because this helped me alot. – Saahir Foux Jul 20 '12 at 22:53
  • 1
    Fyi, for future readers, you MUST also apply the following to your code for the above to work correctly. Change date.replace seen above to "date.replace(/-/g, '')" to make sure it replaces all the hyphens, rather than just the first. Also, you will encounter a 1:1000000 design quirk in parseInt with your day variable if date.substring(2,4) is either '08' or '09. See the next link for details and a solution. http://support.microsoft.com/kb/191434 – Saahir Foux Jul 21 '12 at 06:19
  • if I'm not wrong this should be written without ' . date = date.replace(/-/g, ''); Otherwise it will look for a string like "/-/g". – sataniccrow Apr 02 '14 at 07:43
  • 1
    and I'm 100% sure that your leap year code is bugged (it validates as true even a date like this 02-29-2001) – sataniccrow Apr 04 '14 at 08:23
  • 2
    @sataniccrow now it is fixed – Vitaly Olegovitch Dec 17 '15 at 16:30
  • @VitalijZadneprovskij if i give input date as "abc" or "123" it gives true. I think this validation is not fully complete. – SkyWalker Apr 13 '16 at 08:48
5

How about validating dates in "ANY" date format? I've been using the DateJS library and adding it to existing forms to ensure that I get valid dates & times formatted the way that I want. The user can even enter things like "now" and "tomorrow" and it will be converted into a valid date.

Here's the dateJS library: http://www.datejs.com/

and here's a jQuery tip that I wrote: http://www.ssmedia.com/utilities/jquery/index.cfm/datejs.htm

James Moberg
  • 4,360
  • 1
  • 22
  • 21
4

I would use Moment.js for this task. It makes it very easy to parse dates and it also provides support to detect a an invalid date1 in the correct format. For instance, consider this example:

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)

First moment(.., formats) is used to parse the input according to the localized format supplied. Then the isValid function is called on the resulting moment object so that we can actually tell if it is a valid date.

This can be used to trivially derive the isValidDate method:

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

1 As I can find scarce little commentary on the matter, I would only use moment.js for dates covered by the Gregorian calendar. There may be plugins for other (including historical or scientific) calendars.

user2864740
  • 60,010
  • 15
  • 145
  • 220
4

I use this regex for validating MM-DD-YYYY:

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;
  }
}

It will match only valid months and you can use / - or . as separators.

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
3

This function will validate the date to see if it's correct or if it's in the proper format of: DD/MM/YYYY.

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.log(isValidDate('10-12-1961'));
console.log(isValidDate('12/11/1961'));
console.log(isValidDate('02-11-1961'));
console.log(isValidDate('12/01/1961'));
console.log(isValidDate('13-11-1961'));
console.log(isValidDate('11-31-1961'));
console.log(isValidDate('11-31-1061'));
Jongware
  • 22,200
  • 8
  • 54
  • 100
3

what isn't working about it? here's a tested version:

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
Roel
  • 3,089
  • 2
  • 30
  • 34
Owen
  • 82,995
  • 21
  • 120
  • 115
  • what if no matches are found then new Date(match[3], match[1] - 1, match[2]); won't work -- update: fixed it – Roel Dec 18 '20 at 14:49
2

Simple way to solve

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);
Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
Srimitha
  • 37
  • 1
1

You can simplify it somewhat by changing the first two lines of the function to this:

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

Or, just change the parameter to the RegExp constructor to be

^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$
Kevin Gorski
  • 3,745
  • 1
  • 22
  • 16
0

pass this function to date with format //10-10-2012 and id of object.

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('');  
    }
  }
}
j0k
  • 22,600
  • 28
  • 79
  • 90
Jawad
  • 1
  • 1
0

This is for validating the date string in formate dd.mm.yyyy It is easy to customize it. You just need to adjust the pos1 and pos2 in 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;
}
Jyotish
  • 1
  • 1
0
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");
}
Ashley Medway
  • 7,151
  • 7
  • 49
  • 71
Adam
  • 1
0
<!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> 
Mayur Narula
  • 150
  • 1
  • 4
0

Please find in the below code which enables to perform the date validation for any of the supplied format or based on user locale to validate start/from and end/to dates. There could be some better approaches but have come up with this. Have tested it for the formats like: MM/dd/yyyy, dd/MM/yyyy, yyyy-MM-dd, yyyy.MM.dd, yyyy/MM/dd and dd-MM-yyyy.

Note supplied date format and date string go hand in hand.

<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');" />
Dinesh Lomte
  • 569
  • 7
  • 5
0

If your date needs to match DD.MM.YYYY and use AngularJS, use the following code:

$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.log($scope.validDate('22.04.2001'));
            console.log($scope.validDate('03.10.2001'));
            console.log($scope.validDate('30.02.2001'));
            console.log($scope.validDate('23.09.2016'));
            console.log($scope.validDate('29.02.2016'));
            console.log($scope.validDate('31.02.2016'));

More about the scope object can be found here. Without AngularJS, simply change the first line to:

ValidDate = new function(value) {

And call it using:

var MyDate= ValidDate('29.09.2016');
Eric P
  • 4,587
  • 6
  • 24
  • 19
  • This isn't an answer to the Original question but I see that the question has changed to some kind of a knowledge base article for JS and dates. Could you add some info about the `$scope` object, as far as I know it is not a standard object and would create an object reference error. – SaschaM78 Sep 23 '16 at 07:17
  • 1
    I've used this solution in my AngularJs Project. $Scope [link](https://docs.angularjs.org/guide/scope) is an object that refers to the application model. If you paste this code into a project without AngularJs, you have to remove the $scope object to get it work. – Dominik Baran Sep 29 '16 at 08:37
  • Thanks for clarifying, now the answer makes sense to me. – SaschaM78 Sep 29 '16 at 09:05
0

DateFormat = DD.MM.YYYY or 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';} 
}
Fox
  • 1
0

try this:

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;
              }                   
}
slfan
  • 8,950
  • 115
  • 65
  • 78
0

Short and fast.

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.log('02-29-2000', dateValid('02-29-2000'));
console.log('02-29-2001', dateValid('02-29-2001'));
console.log('12-31-1970', dateValid('12-31-1970'));
console.log('Hello', dateValid('Hello'));
Adam Leggett
  • 3,714
  • 30
  • 24
  • Please add some explanation to your code such that others can learn from it - for example, what's that part with `2741` about? – Nico Haase Mar 01 '19 at 13:39
  • @NicoHaase added some code comments. 2741 is a bitmap where 1 means a month has 31 days, 0 means otherwise. – Adam Leggett Mar 04 '19 at 15:46
  • @AdamLeggett Replacing `(!(y % 4) && y % 100 || !(y % 400)))` with `!(y%4 || (!(y%100) && y%400)) )` fixes a bug revealed by testing with non millennial leap years - the `y % 100` expression is not being converted to a boolean, so it doesn't get coerced to `1` in the numerical comparison. – traktor Oct 31 '20 at 02:34
0

German Variant, but could be adapted to 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
}
0

Expanding on "Short and Fast" above by @Adam Leggett, as cases like "02/30/2020" return true when it should be false. I really dig the bitmap though...

For a MM/DD/YYYY date format validation:

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.log(dateValid('02/28/2020')) // true
console.log(dateValid('02/29/2020')) // true
console.log(dateValid('02/30/2020')) // false
console.log(dateValid('01/31/2020')) // true
console.log(dateValid('01/31/2000')) // true
console.log(dateValid('04/31/2020')) // false
console.log(dateValid('04/31/2000')) // false
console.log(dateValid('04/30/2020')) // true
console.log(dateValid('01/32/2020')) // false
console.log(dateValid('02/28/2021')) // true
console.log(dateValid('02/29/2021')) // false
console.log(dateValid('02/30/2021')) // false
console.log(dateValid('02/28/2000')) // true
console.log(dateValid('02/29/2000')) // true
console.log(dateValid('02/30/2000')) // false
console.log(dateValid('02/28/2001')) // true
console.log(dateValid('02/29/2001')) // false
console.log(dateValid('02/30/2001')) // false

For a MM-DD-YYYY date format validation: Replace \/ in the pattern for match by -.

Patrick_B
  • 1
  • 2
-2
<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>