55

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

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

如果我将格式更改为“dd/M/yy”并选择像 2011 年 8 月 13 日这样的日期,它可以在 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>
4

12 回答 12

53

四个小时后,我终于偶然发现了答案。出于某种原因,Chrome 似乎有一些内在的偏好,即使用美国日期格式,其中 IE 和 FireFox 能够明智地使用操作系统上的区域设置。

jQuery.validator.methods["date"] = function (value, element) { return true; } 
于 2011-08-02T06:15:16.073 回答
50

您可以使用此处提供的 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");
}
于 2012-11-23T12:02:27.980 回答
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);
};
于 2013-04-04T12:45:10.923 回答
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 中的这个愚蠢问题。

于 2011-11-02T05:53:33.280 回答
2

这在 .net mvc4 中仍然是一个问题,尽管 jQuery 验证插件中有明确的文档不使用它,但EditorFor DateTime仍然会产生一个属性!!!data-val-date希望微软能解决这个问题,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);
于 2013-09-26T10:17:14.267 回答
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 中没有上述代码的情况下遇到此问题。

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

我在这里搜索问题时发现了这个代码片段

于 2016-04-28T01:14:49.787 回答
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;
        });
}
于 2016-09-26T14:39:40.533 回答
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"
    );
于 2016-12-13T20:47:11.427 回答
0

应该将您在 validate 中定义的 dateRule 方法更改为(例如,正则表达式只是一个简单的方法):

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

您可以根据需要切换正则表达式。我从这里得到了这个日期的正则表达式,它支持 M/D/YY 或 M/D/YYYY 或 MM/DD/YYYY 或 MM/DD/YY:1/1/1920 到 12/31/2019;2 月 29 日和 30 日始终允许

^((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})))$
于 2011-08-02T03:21:53.997 回答
0

我还找到了一个似乎适用于任何文化的解决方案。

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

它需要您修改实际的 jquery.valdiation.min.js 文件,但到目前为止它对我有用。

于 2012-09-19T15:57:12.330 回答
0

这是唯一对我有用的解决方案: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));
            }
        }
    }); 
于 2015-03-11T10:01:59.103 回答
0

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

$.validator.addMethod("date", function (value, element) {
    var result = true;
    try {
        $.datepicker.parseDate('dd/mm/yy', value);
    }
    catch (err) {
        result = false;
    }
    return result;
});
于 2018-01-18T02:26:30.910 回答