44

I am taking input of date of birth and date of death. Validation required

  1. date of death should be more than date of birth
  2. Date format to be dd/mm/yyyy
  3. Dates to be less than or equal to today.

Validate doesn't work as expected and can't figure out the problem. Please help.

Fiddle code

JS libraries used

  1. JQuery UI for Calendar/Datepicker
  2. JQuery validate for form validation
  3. Additional methods for validation library

    var today = new Date();
    var authorValidator = $("#itemAuthorForm").validate({
    rules : {
        dateOfBirth : {
            required : false,
            date : true,
            dateITA : true,
            dateLessThan : '#expiredDate'
        },
        expiredDate : {
            required : false,
            date : true,
            dateITA : true,
            dateGreaterThan : "#dateOfBirth"
        }
    },
    onfocusout : function(element) {
        if ($(element).val()) {
            $(element).valid();
        }
    }
    });
    var dateOptionsDOE = {
    maxDate : today,
    dateFormat : "dd/mm/yy",
    changeMonth : true,
    changeYear : true,
    onClose : function(selectedDate) {
        $("#dateOfBirth").datepicker("option", "maxDate", selectedDate);
    }
    };
    var dateOptionsDOB = {
    maxDate : today,
    dateFormat : "dd/mm/yy",
    changeMonth : true,
    changeYear : true,
    onClose : function(selectedDate) {
        $("#expiredDate").datepicker("option", "minDate", selectedDate);
    }
     };
    
    jQuery.validator.addMethod("dateGreaterThan",
    function(value, element, params) {
    if ($(params).val() === "")
        return true;
    
    if (!/Invalid|NaN/.test(new Date(value))) {
        return new Date(value) > new Date($(params).val());
    }
    return isNaN(value) && isNaN($(params).val())
            || (Number(value) > Number($(params).val()));
            }, 'Must be greater than {0}.');
            jQuery.validator.addMethod("dateLessThan",
            function(value, element, params) {
    if ($(params).val() === "")
        return true;
    
    if (!/Invalid|NaN/.test(new Date(value))) {
        return new Date(value) < new Date($(params).val());
    }
    
    return isNaN(value) && isNaN($(params).val())
            || (Number(value) < Number($(params).val()));
            }, 'Must be less than {0}.');
            $("#expiredDate").datepicker(
        $.extend({}, $.datepicker.regional['en-GB'], dateOptionsDOE));
            $("#dateOfBirth").datepicker(
        $.extend({}, $.datepicker.regional['en-GB'], dateOptionsDOB));
    
Cipher
  • 455
  • 1
  • 6
  • 8
  • when you are writiing: dateFormat : "dd/mm/yy" Does it also include "dd.mm.yy" and "dd-mm-yy" ?? – dinesh kandpal Sep 07 '17 at 07:49
  • I have used simplify regex: jQuery.validator.addMethod("checkDateOfBirth", function(value) { return value.match(/^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$/); }, "Invalid Date"); month(1-12) day(1-31) year(19xx - 20xx) – nosensus Dec 10 '18 at 13:38

6 Answers6

47

This will also checks in leap year. This is pure regex, so it's faster than any lib (also faster than moment.js). But if you gonna use a lot of dates in ur code, I do recommend to use moment.js

var dateRegex = /^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-.\/])(?:1[012]|0?[1-9])\1(?:1[6-9]|[2-9]\d)?\d\d(?:(?=\x20\d)\x20|$))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\x20[AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$/;

console.log(dateRegex.test('21/01/1986'));

enter image description here

http://regexper.com/....

Daut
  • 2,537
  • 1
  • 19
  • 32
Leonardo Cavalcante
  • 1,274
  • 1
  • 16
  • 26
22

You don't need the date validator. It doesn't support dd/mm/yyyy format, and that's why you are getting "Please enter a valid date" message for input like 13/01/2014. You already have the dateITA validator, which uses dd/mm/yyyy format as you need.

Just like the date validator, your code for dateGreaterThan and dateLessThan calls new Date for input string and has the same issue parsing dates. You can use a function like this to parse the date:

function parseDMY(value) {
    var date = value.split("/");
    var d = parseInt(date[0], 10),
        m = parseInt(date[1], 10),
        y = parseInt(date[2], 10);
    return new Date(y, m - 1, d);
}
izstas
  • 5,004
  • 3
  • 42
  • 56
  • Thank you for spending time to read through my code.Code seems to work after incorporating your suggestions. Bingo! :)... most of my time was consumed in finding additional methods for validator and also en-GB formatting for UI widgets. I should have removed date:true rule :) – Cipher Jun 24 '14 at 09:43
  • It always returns a date even if I enter an invalid date. – RN Kushwaha May 22 '16 at 16:38
  • What if you want to parse hours and minutes? – FrenkyB Feb 02 '17 at 09:10
  • this not work if you write 12/13/1991 this shows as a fine date when a month 13th not exist – angel Oct 11 '17 at 15:47
  • This function is not designed to validate the date. The OP is already using a `dateITA` validator, and this function just aids in the implementation of additional `dateGreaterThan` and `dateLessThan` validators. – izstas Oct 11 '17 at 16:36
17

If you use the moment js library it can easily be done like this -

jQuery.validator.addMethod("validDate", function(value, element) {
        return this.optional(element) || moment(value,"DD/MM/YYYY").isValid();
    }, "Please enter a valid date in the format DD/MM/YYYY");
UBF
  • 171
  • 1
  • 3
  • when you are validating date in ''DD/MM/YYYY" Does it also include dateFormat : "dd-mm-yy" and dd.mm.yy ??? – dinesh kandpal Sep 07 '17 at 07:51
  • If you add OR, will do the trick: return this.optional(element) || moment(value,"DD/MM/YYYY").isValid() || moment(value,"DD-MM-YYYY").isValid(); – Yogurtu Mar 27 '18 at 20:31
  • This will fail for : moment(1,"DD/MM/YYYY").isValid(); moment will return true . – Shan Apr 13 '19 at 07:18
10

I encountered a similar problem in my project. After struggling a lot, I found this solution:

if ($.datepicker.parseDate("dd/mm/yy","17/06/2015") > $.datepicker.parseDate("dd/mm/yy","20/06/2015"))
    // do something

You DO NOT NEED plugins like jQuery Validate or Moment.js for this issue. Hope this solution helps.

RushabhG
  • 352
  • 3
  • 11
4

This works fine for me.

$(document).ready(function () {
       $('#btn_move').click( function(){
           var dateformat = /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/;
           var Val_date=$('#txt_date').val();
               if(Val_date.match(dateformat)){
              var seperator1 = Val_date.split('/');
              var seperator2 = Val_date.split('-');

              if (seperator1.length>1)
              {
                  var splitdate = Val_date.split('/');
              }
              else if (seperator2.length>1)
              {
                  var splitdate = Val_date.split('-');
              }
              var dd = parseInt(splitdate[0]);
              var mm  = parseInt(splitdate[1]);
              var yy = parseInt(splitdate[2]);
              var ListofDays = [31,28,31,30,31,30,31,31,30,31,30,31];
              if (mm==1 || mm>2)
              {
                  if (dd>ListofDays[mm-1])
                  {
                      alert('Invalid date format!');
                      return false;
                  }
              }
              if (mm==2)
              {
                  var lyear = false;
                  if ( (!(yy % 4) && yy % 100) || !(yy % 400))
                  {
                      lyear = true;
                  }
                  if ((lyear==false) && (dd>=29))
                  {
                      alert('Invalid date format!');
                      return false;
                  }
                  if ((lyear==true) && (dd>29))
                  {
                      alert('Invalid date format!');
                      return false;
                  }
              }
          }
          else
          {
              alert("Invalid date format!");

              return false;
          }
       });
   });
Jonathan Sayce
  • 9,359
  • 5
  • 37
  • 51
4

This validates dd/mm/yyy dates. Edit your jquery.validate.js and add these.

Reference(Regex): Regex to validate date format dd/mm/yyyy

dateBR: function( value, element ) {
    return this.optional(element) || /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/.test(value);
}

messages: {
    dateBR: "Invalid date."
}

classRuleSettings: {
    dateBR: {dateBR: true}
}

Usage:

$( "#myForm" ).validate({
    rules: {
        field: {
            dateBR: true
        }
    }
});
Pankaj Bisht
  • 986
  • 1
  • 8
  • 27
dubonzi
  • 1,492
  • 1
  • 21
  • 31