Chrome中不显眼的验证无法验证dd/mm/yyyy格式。

55

我想尝试在不同浏览器中使用最简单的日期选择器。我怀疑我做错了一些非常简单的事情,但是经过大量搜索,我仍然没有找到解决方案。以下是一些代表我尝试的示例代码。

如果我在Chrome(v12.0.742.122)中选择一个日期选择器中的日期,例如13/08/2011,即使我明确将格式指定为“dd/mm/yy”,jQuery验证逻辑也不允许页面提交。

如果我将格式更改为“dd/M/yy”并选择像13/Aug/2011这样的日期,则它在Chrome中可以工作,但是对于IE(v8.0.7600.16385)而言,它无法提交。 在FireFox(v3.6.18)中,两种格式都可以工作。

我需要哪个验证脚本才能支持Chrome中的“dd/mm/yy”日期格式?

<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>
12个回答

52
四个小时后,我终于偶然发现了这个答案。由于某种原因,Chrome似乎内置了使用美国日期格式的偏好设置,而IE和FireFox能够理性地使用操作系统上的区域设置。
jQuery.validator.methods["date"] = function (value, element) { return true; } 

3
我花了大约一个小时在这里找到你的答案。这行代码完美地运作。 - user1616625
这行代码应该放在哪里? - Rusty
@Rusty,你可以将它放在任何在日期验证之前执行的地方。我把它放在了$(document).ready函数中。 - sipsorcery
27
忽略验证?!你是认真的吗?! - Mehdiway
谢谢你的帮助,让我免去了很多痛苦 :) - AlanMorton2.0
2
请勿使用操作系统的区域设置来处理IE和FireFox浏览器。如果您输入“76/85/2015”,它们会生成一个日期,即使这不是一个有效的日期。只有Chrome能正确地报告它为无效日期。这意味着您永远无法获得客户端验证。 - user3559349

51

您可以使用此处提供的 Globalize.js 插件:https://github.com/jquery/globalize

然后,只需在您网站的主脚本文件中重新定义 validate 方法,如下所示(避免编辑 jquery.validate.js 库文件,因为您可能希望将其更新到未来):

$.validator.methods.date = function (value, element) {
    return this.optional(element) || Globalize.parseDate(value, "d/M/y", "en");
}

7
这应该被视为答案。+1 - Darbio
3
给其他人的提示:应该有一个大写字母"M",即 d/M/y 中的小标记表示分钟,即使它不应该工作也会起作用! - Martin

22

我知道我有点晚了,但这是我用于解决Chrome验证不接受英国格式日期的解决方案。一个简单的即插即用验证,它不依赖于任何插件或修改任何文件。它将接受从1900年1月1日至2999年31月31日之间的任何日期,因此可以使用美国或英国格式。显然会有一些无效的日期通过验证,但你可以根据自己的需要调整正则表达式。这满足了我的需求,因为它将在网站的低流量区域中使用,同时还具有服务器端验证。涉及的网站区域采用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);
};

2
我使用了一个比这个正则表达式更复杂一些,但比另一个答案中的庞大正则表达式简单一些的正则表达式。它不检查字符串的结尾,以便允许后面跟着时间。 var dateRegex = /^(0?[1-9]|[12]\d|3[01])/(0?[1-9]|10|11|12)/(19|20)\d\d\D/; 超出范围的问题由日期或日期时间选择器的约束处理。 - David
3
实际上,现在它支持没有尾随字符的情况,假设仅为日期(之前是针对日期时间处理的)var dateRegex = /^(0?[1-9]|[12]\d|3[01])/(0?[1-9]|10|11|12)/(19|20)\d\d(\D.*)?$/; - David
感谢你们的帮助,David :). 为了澄清对于任何人来说,第一个接受英国日期后跟非数字和其他任何内容。而第二个只接受英国格式日期。它们提供了更好的匹配英国格式日期,尽管仍会有一些边缘情况被忽略(例如31/02)。 - webdevduck
谢谢你!太棒了。 - jonatanes
这是最佳的实用响应,结合了客户端和服务器端验证。我刚刚花了几个小时来解决全球化和相关的全球化js文件,在IE、Chrome和Firefox中无法让它们正常工作,最终不得不撤销所有操作。如果我一开始就使用这个,我只需要花费10分钟,用户就看不到任何问题。 - Simon Molloy
谢谢您...这比添加另一个jQuery库要干净得多。 - Andrew

18

看起来这个问题已经被报告给了jQuery团队。

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

目前的解决方法似乎是在additional-methods.js中使用dateITA。

它看起来像下面这样:

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"
);

如果你添加了该验证器,你就可以将你的日期选择器附加到“.dateITA”类。

到目前为止,这对我来说已经很有效,帮助我解决了Chrome中这个愚蠢的问题。


2
我们用以下工具来处理项目:
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;
        });
}

2
我发现纠正这个错误最简单的方法是,在调用验证文件后添加以下代码片段;
    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;
    }

即使在2016年的版本中,我仍然在Chrome中遇到了这个问题,而在Firefox中没有上述代码。

这是我的首选解决方案,因为它不需要任何额外的库或插件就可以工作。

我在谷歌搜索中找到了这段代码片段(链接)


2

这在 .net mvc4 中仍然是一个问题,其中 EditorFor DateTime 仍会生成一个 data-val-date 属性,尽管 jQuery 验证插件的文档明确指出不要使用它!!!希望微软能够修复这个问题,data-val-date 永远不再出现!

与此同时,您可以通过 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
    }
});

如果不想使用yepnope/modernizr,并且想要去掉dateITA方法中的UTC组件(如果使用此库输入本地时间,则日期在月份的第一天或最后一天将无法始终验证,除非在格林威治线上 - 即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);

1

愿这段代码能帮到您。

$.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"
    );

你从哪里得到这段代码的?是自己写的吗?你为什么认为它会起作用? - T-Heron

0

答案应该包含比简单链接更多的信息。你至少应该将一些内容总结到你的答案中。 - Liam

0

或者我们可以尝试覆盖验证器而不是忽略它。

$.validator.addMethod("date", function (value, element) {
    var result = true;
    try {
        $.datepicker.parseDate('dd/mm/yy', value);
    }
    catch (err) {
        result = false;
    }
    return result;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接