55

I'm trying to use the simplest possible scenario using a date picker in different browsers. I suspect I'm doing something very simple the wrong way but after lots of searching around I still haven't found a solution. Below is some sample code that represents what I'm attempting.

If I use Chrome (v12.0.742.122) and pick a date from the picker like 13/08/2011 the jQuery validation logic will not allow the page to submit even though I've explicitly specified the format as 'dd/mm/yy'.

If I change the format to 'dd/M/yy' and choose a date like 13/Aug/2011 it works in Chrome but then won't submit for me in IE (v8.0.7600.16385). In FireFox (v3.6.18) both formats work.

What validation script do I need to be able to support date formats of 'dd/mm/yy' in Chrome?

<html>
 <head>
  <link rel="stylesheet" type="text/css" href="jquery-ui.css" />
  <script type="text/javascript" src="jquery-1.4.4.js"></script>
  <script type="text/javascript" src="jquery.validate.js"></script>
  <script type="text/javascript" src="jquery.validate.unobtrusive.js"></script>
  <script type="text/javascript" src="jquery-ui.js"></script>
  <script type="text/javascript">
      $(document).ready(function () {
    $('.date').datepicker({ dateFormat: 'dd/mm/yy' });
            $.validator.addMethod("dateRule", function(value, element) {
      return true;
    },
    "Error message");
      });
  </script>
 </head>
 <body>
    <form>
        Date: <input type="text" name="myDate" class="date dateRule" />
        <input type="submit" />
    </form>
 </body>
</html>
sipsorcery
  • 30,273
  • 24
  • 104
  • 155

12 Answers12

52

Four hours later I finally stumbled across the answer. For some reason Chrome seems to have some inbuilt predilection to use US date formats where IE and FireFox are able to be sensible and use the regional settings on the OS.

jQuery.validator.methods["date"] = function (value, element) { return true; } 
Community
  • 1
  • 1
sipsorcery
  • 30,273
  • 24
  • 104
  • 155
  • 3
    It took me about an hour to find your answer here. This line of code works perfectly. – user1616625 Feb 13 '14 at 10:30
  • Where is this line supposed to be placed? – Rusty Aug 05 '15 at 13:43
  • @Rusty you could put it pretty much anywhere that will execute it prior to your date validation needing to occur. I have it in the $(document).ready function. – sipsorcery Aug 05 '15 at 22:25
  • 27
    This ignores the validation !! Are you serious ?! – Mehdiway Oct 12 '15 at 13:46
  • Thanks for the help, saved me a lot of pain :) – AlanMorton2.0 Nov 11 '15 at 10:52
  • 2
    `IE and FireFox` DO NOT use the _regional settings on the OS_ - its just that that if your enter `76/85/2015` they produce a date even through its not a valid date. Only Chome reports it correctly as an invalid date. This answer means you never get client side validation. –  Nov 01 '16 at 10:59
51

You can use the Globalize.js plugin available here: https://github.com/jquery/globalize

Then simply redefine the validate method in your web site's main script file like so (avoid editing the jquery.validate.js library file as you may want to update it in future):

$.validator.methods.date = function (value, element) {
    return this.optional(element) || Globalize.parseDate(value, "d/M/y", "en");
}
magritte
  • 7,396
  • 10
  • 59
  • 79
22

I know I'm a bit late to the party, but here's the solution I used to Chrome validation not accepting UK format dates. A simple plug and play validation, it doesn't rely on any plugins or modifying any files. It will accept any date between 1/1/1900 and 31/31/2999, so US or UK format. Obviously there are invalid dates that will sneak past, but you can tweak the regex to your heart's content. This met my needs as it will be used on a low traffic area of the site, with server-side validation. The area of the site in question is built with ASP.net MVC.

jQuery.validator.methods.date = function(value, element) {
    var dateRegex = /^(0?[1-9]\/|[12]\d\/|3[01]\/){2}(19|20)\d\d$/;
    return this.optional(element) || dateRegex.test(value);
};
webdevduck
  • 563
  • 5
  • 18
  • 2
    I used a regex that's a bit more complex than this one, but less complex than the massive one in another answer. It doesn't check for the end of the string, in order to allow times to follow. var dateRegex = /^(0?[1-9]|[12]\d|3[01])\/(0?[1-9]|10|11|12)\/(19|20)\d\d\D/; Out of range issues are handled by the constraint of the date or datetime picker. – David Apr 10 '13 at 01:29
  • 3
    Actually, make that var dateRegex = /^(0?[1-9]|[12]\d|3[01])\/(0?[1-9]|10|11|12)\/(19|20)\d\d(\D.*)?$/; Now it supports no trailing characters in cases where it's only a date (I was working with datetimes) – David Apr 10 '13 at 02:21
  • Thanks for those David :). Just to clarify for anyone finding this, the top one accepts a UK date followed by a non-digit and then anything else. The bottom one will accept a UK format date only. They provide a much better match for UK format only dates, although there will still be a few edge cases missed (such as 31/02). – webdevduck Apr 16 '13 at 09:54
  • Thanks you! Awesome – jonatanes Oct 08 '16 at 22:00
  • This is the best pragmatic response combining client and server side validation. I've just spent several hours wrestling with the globalize and related globalize js files without getting them to work in all of IE, Chrome and Firefox and eventually backing everything out. If I'd used this from the start I would have spent 10 minutes with no issues evident to the user. – Simon Molloy Mar 03 '17 at 21:31
  • Thank You...This is so much cleaner then adding yet another jquery library. – Andrew Sep 28 '18 at 01:50
18

Looks like this issue has been raised with the JQuery team.

https://github.com/jzaefferer/jquery-validation/issues/153

Looks like the workaround for now is to use dateITA in additional-methods.js

It looks like this:

jQuery.validator.addMethod(
    "dateITA",
    function(value, element) {
        var check = false;
        var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
        if( re.test(value)){
            var adata = value.split('/');
            var gg = parseInt(adata[0],10);
            var mm = parseInt(adata[1],10);
            var aaaa = parseInt(adata[2],10);
            var xdata = new Date(aaaa,mm-1,gg);
            if ( ( xdata.getFullYear() == aaaa ) 
                   && ( xdata.getMonth () == mm - 1 ) 
                   && ( xdata.getDate() == gg ) )
                check = true;
            else
                check = false;
        } else
            check = false;
        return this.optional(element) || check;
    },
    "Please enter a correct date"
);

If you add that validator you can then attach your datepicker to the '.dateITA' class.

Thus far this has worked well for me to get me beyond this stupid issue in Chrome.

mezoid
  • 28,090
  • 37
  • 107
  • 148
2

This remains a problem in .net mvc4, where the EditorFor DateTime still produces a data-val-date attribute, despite clear documentation in the jQuery validation plugin not to use it!!! Hopefully microsoft fixes this and data-val-date is never heard of again!

In the meantime you could use the suggested library via modernizr:

yepnope({
    test: isNaN(Date.parse("23/2/2012")),
    nope: 'http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/additional-methods.min.js',
    complete: function () {
        $.validator.methods.date = $.validator.methods.dateITA
    }
});

or if not wanting to use yepnope/modernizr, and to get rid of the UTC component of the dateITA method (if using this library to enter a local time, dates will not always validate on the 1st or last day of the month unless on the Greenwich line - i.e. UTC +0):

(function ($) {
    var invokeTestDate = function () {
        return $.validator.methods.date.call({
            optional: function () {
                return false;
            }, (new Date(2012,8,23)).toLocaleDateString(), null);
    };
    if (invokeTestDate()) {
        return;
    }

    // http://docs.jquery.com/Plugins/Validation/Methods/date

    $.validator.methods.date = function (value, element) {
        //ES - Chrome does not use the locale when new Date objects instantiated:
        //return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
        var d = new Date();
        return this.optional(element) || !/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
    }
})(jQuery);
Liam
  • 27,717
  • 28
  • 128
  • 190
Brent
  • 4,611
  • 4
  • 38
  • 55
2

I found the simplest correction of this error to be the following code snippet after calling your validation file;

    jQuery.validator.methods["date"] = function (value, element){
        var shortDateFormat = "dd/mm/yy";
        var res = true;
        try {
            $.datepicker.parseDate(shortDateFormat, value);
        } catch (error) {
            res = false;
        }
        return res;
    }

Even in versions found in 2016 im still having this issue without the above code in Chrome and not Firefox.

This is my preferred solution as it does not require any additional libraries or plugins to work.

I found this code snippet while googling the issue here.

Tarquin
  • 482
  • 2
  • 6
  • 21
2

We use the following to work on our projects;

if ($.validator) {
    $.validator.addMethod("date",
        function (value, element, params) {
            if (this.optional(element)) {
                return true;
            }

            var ok = true;
            try {
                $.datepicker.parseDate("dd/mm/yy", value);
            }
            catch (err) {
                ok = false;
            }
            return ok;
        });
}
DiskJunky
  • 4,750
  • 3
  • 37
  • 66
1

May this code help you.

$.validator.addMethod(
         "date",
         function(value, element) {
              var check = false;
              var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
              var reBR = /^\d{4}\-\d{1,2}\-\d{1,2}$/;
              if( re.test(value)){
                   var adata = value.split('/');
                   var gg = parseInt(adata[0],10);
                   var mm = parseInt(adata[1],10);
                   var aaaa = parseInt(adata[2],10);
                   var xdata = new Date(aaaa,mm-1,gg);
                   if ( ( xdata.getFullYear() == aaaa ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == gg ) )
                        check = true;
                   else
                        check = false;
              } else if( reBR.test(value)){
                   var adata = value.split('-');
                   var aaaa = parseInt(adata[0],10);
                   var mm = parseInt(adata[1],10);
                   var gg = parseInt(adata[2],10);
                   var xdata = new Date(aaaa,mm-1,gg);
                   if ( ( xdata.getFullYear() == aaaa ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == gg ) )
                        check = true;
                   else
                        check = false;
              } else
                   check = false;
                   console.log(check);
              return this.optional(element) || check;
         },
         "Por favor insira uma data válida"
    );
0

I also found a solution that appears to work for any culture.

http://devdens.blogspot.com/2011/11/jquery-validation-fix-for-date-format_29.html

It requires you to modify the actual jquery.valdiation.min.js file, but so far it's working for me.

aaron
  • 349
  • 3
  • 10
  • Answers should contain more information than simply a link. You should (as a bear minimum) summarise some of the content into your answer. – Liam Sep 19 '14 at 14:01
0

This is the only solution that worked for me: http://www.codeproject.com/Tips/579279/Fixing-jQuery-non-US-Date-Validation-for-Chrome

 jQuery.extend(jQuery.validator.methods, {
        date: function (value, element) {
            var isChrome = window.chrome;
            // make correction for chrome
            if (isChrome) {
                var d = new Date();
                return this.optional(element) || 
                !/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
            }
            // leave default behavior
            else {
                return this.optional(element) || 
                !/Invalid|NaN/.test(new Date(value));
            }
        }
    }); 
Aleksandr M
  • 24,264
  • 12
  • 69
  • 143
Jodda
  • 25
  • 4
0

Or we might try to overwrite the validator instead of ignoring it.

$.validator.addMethod("date", function (value, element) {
    var result = true;
    try {
        $.datepicker.parseDate('dd/mm/yy', value);
    }
    catch (err) {
        result = false;
    }
    return result;
});
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Kevin Wong
  • 92
  • 9
0

should change the dateRule method you define in validate to (the regex is just a simple one for example):

$.validator.addMethod(
    "dateRule",
    function(value, element) {
        return value.match(/^\d\d?\/\d\d?\/\d\d$/);
    },
    "Please enter a date in the format dd/mm/yy"
);

you can switch the regex for whatever you wish. I got this regex for date from here which supports M/D/YY or M/D/YYYY or MM/DD/YYYY or MM/DD/YY: 1/1/1920 through 12/31/2019; Feb 29 and 30 always allowed

^((0?[13578]|10|12)(-|\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[01]?))(-|\/)((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1}))|(0?[2469]|11)(-|\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[0]?))(-|\/)((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1})))$
Calvin
  • 1,305
  • 8
  • 17
  • That would be the next step. At the moment I can't even get Chrome to pass the validation by always returning true. – sipsorcery Aug 02 '11 at 03:42
  • i can't replicate your problem. i seem to be able to submit a form. could you try not including jquery.validate.unobtrusive.js and adding a $('form').validate(); – Calvin Aug 02 '11 at 03:54
  • Excluding the jquery.validate.unobtrusive.js gets Chrome submitting the form. Now I need to understand how to configure the unobtrusive validation rule to work. – sipsorcery Aug 02 '11 at 04:23
  • this might help: [click here](http://stackoverflow.com/questions/5425783/help-needed-with-custom-jquery-validation-and-unobtrusive-javascipt/6702262#6702262) – Calvin Aug 02 '11 at 04:55
  • This doesn't seem to help in getting Chrome to validate dd/mm/yyyy since it also allows mm/dd/yyyy – mezoid Nov 02 '11 at 05:20