Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date validation allows invalid dates in some browsers #6878

Open
RobJohnston opened this issue Jun 18, 2015 · 15 comments
Open

Date validation allows invalid dates in some browsers #6878

RobJohnston opened this issue Jun 18, 2015 · 15 comments

Comments

@RobJohnston
Copy link
Contributor

Riddle me this... Go to the existing Form validation page and enter the date "2016-02-30".

  • In FF 38.0, you will get the message "Please enter a valid date".
  • In IE 11, the date will be accepted.
  • In Chrome 43, the date will be accepted (of course, in the form "30/02/2016).

I have a local version of WET 4.0.9 and it's behaving a bit different in that for Chrome, it will say "This field is required" using this invalid date. No difference for FF or IE.

@DavidCampbellCSC
Copy link

I have a similar issue with Safari (does not accept dashes only slashes). the accepted solution on Stackoverflow is to use javascript like this
var myDate1 = Date.parseExact("2011-04-12", "yyyy-MM-dd");
is form validation using Date.parseExact or Date.parse?

@pjackson28
Copy link
Member

@RobJohnston Perhaps Chrome security measures are kicking in blocking jQuery validation from loading? It sounds like regular HTML5 validation is occurring which only happens when the JS doesn't load.

@DavidCampbellCSC We rely on jQuery validation for that validation. Here is what they use:

        // http://jqueryvalidation.org/date-method/
        date: function( value, element ) {
            return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
        },

        // http://jqueryvalidation.org/dateISO-method/
        dateISO: function( value, element ) {
            return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
        },

@RobJohnston
Copy link
Contributor Author

Seems related to how each browser handles dates in javascript. Try loading this page:

<html>
  <head>
  <script type="text/javascript">
    var d1 = new Date("2016-02-30");
    alert(d1);
  </script>
</head>
  <body>
  </body>
</html>

The result is that FF will show that it's an invalid date, but IE and Chrome change it by assuming it's missing it's UTC time and show it as "Mon February 29 2016 19:00:00 GMT-0500". Changing the date to 2016-02-31 simply advances the date to March 1st for these two browsers, while FF still knows that it's invalid. This behaviour matches what I see on the current form validation page.

I got no explanation for the difference in Chrome between 4.0.9 and 4.0.14.

@hsrudnicki
Copy link

Based on the above, this issue may require more time to be solved or are you ready to close this issue?

@RobJohnston
Copy link
Contributor Author

I wonder if there is hope, because the following correctly gets the last day of the month for all 3 browsers:

var dt = new Date(2012, 2, 0);
alert(dt); // displays the last day in February.

@hsrudnicki
Copy link

@RobJohnston @pjackson28 @DavidCampbellCSC : Are you ready to close this issue?

@RobJohnston
Copy link
Contributor Author

Looks like jQuery validation knows about the problem and isn't doing anything until they completely replace the date method.

I think that I could overwrite the dateISO method on my page to include a test to see if it's a real-world date with something like this:

wb.doc.on("wb-ready.wb", function (event) {
    $.validator.addMethod("dateISO", function (value, element) {
        var check = true,
            re = /^(\d{4})[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/;
        if (re.test(value)) {
            var dtArray = value.match(re);
            var dtYear = dtArray[1];
            var dtMonth = dtArray[2];
            var dtDay = dtArray[3];

            if (dtMonth == 2) {
                var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
                if (dtDay > 29 || (dtDay == 29 && !isleap)) {
                    check = false;
                }
            }
        }

        return this.optional(element) || check;
    });
});

Comments, anyone? Or else I'm ready to close.

@pjackson28
Copy link
Member

@nschonni What do you recommend we do until jQuery validation replaces the date method? Should we be overriding the dateISO method centrally through WET, leave it for people to override locally, or is there another approach we took?

@nschonni
Copy link
Member

I had a brief chat with @RobJohnston about this and I suggested PR'ing this upstream since it looks like there might be another release soon.
NB: https://en.wikipedia.org/wiki/ISO_8601 It looks like ISO dates actually shouldn't contain / , but I can't fully confirm because of the usual ISO paywall http://www.iso.org/iso/home/standards/iso8601.htm

@RobJohnston
Copy link
Contributor Author

Well then, I might as well check for months that only have 30 days as well:

$.validator.addMethod("dateISO", function (value, element) {
        var check = true,
            re = /^(\d{4})[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/;
        if (re.test(value)) {
            var adata = value.match(re);
            var yyyy = parseInt(adata[1], 10);
            var mm = parseInt(adata[2], 10);
            var dd = parseInt(adata[3], 10);

            if ((mm == 4 || mm == 6 || mm == 9 || mm == 11) && dd == 31) {
                check = false;
            }
            else if (mm == 2) {
                var isLeap = (yyyy % 4 == 0 && (yyyy % 100 != 0 || yyyy % 400 == 0));

                if (dd > 29 || (dd == 29 && !isLeap)) {
                    check = false;
                }
            }
        }

        return this.optional(element) || check;
    });

I've got the tooling at home to do a PR and will try to get it done this weekend.

@RobJohnston
Copy link
Contributor Author

Code in the PR differs from above. Done here: jquery-validation/jquery-validation#1528

@hsrudnicki
Copy link

Based on the above, this issue has been referenced with the other issue 6758, and the both are waiting for your decision in resolving at once the both, please keep this issue's status updated, thank you

@hsrudnicki
Copy link

Is this still an issue? Please update again the status of this, as well in regards to the referenced issue, for the current year, thank you

@RobJohnston
Copy link
Contributor Author

Still an issue. The jQuery validation project isn't interesting in merging the change until the next major version because their current dateISO function accepts many non-ISO formats.

@RobJohnston
Copy link
Contributor Author

FYI: Updated PR located here: jquery-validation/jquery-validation#2032

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants