我司的系统里最近发现了一个神奇的现象:

呵呵呵呵呵。。。。。

我们用的是jQuery.maskedinput这个插件,插件本身只是为了约束格式,并不做validation。所以我们必须自己搞定。思路很简单,插件提供了completed事件,所以只要在用户输入完成后验证字符串是否为合法日期。重点是一个正则表达式。

用大微软的bing搜索后发现了一个支持mm/dd/yyyy并可以验证闰年的正则:

^((0[13578]|1[02])[\/.]31[\/.](18|19|20)[0-9]{2})|((01|0[3-9]|1[1-2])[\/.](29|30)[\/.](18|19|20)[0-9]{2})|((0[1-9]|1[0-2])[\/.](0[1-9]|1[0-9]|2[0-8])[\/.](18|19|20)[0-9]{2})|((02)[\/.]29[\/.](((18|19|20)(04|08|[2468][048]|[13579][26]))|2000))$

对于闰年、非闰年可以正确处理2月28,29。当然2月30,31也是一直不允许的。

最后我们的HTML:

<div class="form-group">
    <label for="DOB">Try input 02/29/1995 and 02/29/1996 or 02/30/yyyy, 02/31/yyyy</label>
    <input id="DOB" name="DOB" type="text" value="" class="form-control" />
    <span id="validate-error-info" class="label label-danger"></span>
</div>

JS:

var dateRegex = /^((0[13578]|1[02])[\/.]31[\/.](18|19|20)[0-9]{2})|((01|0[3-9]|1[1-2])[\/.](29|30)[\/.](18|19|20)[0-9]{2})|((0[1-9]|1[0-2])[\/.](0[1-9]|1[0-9]|2[0-8])[\/.](18|19|20)[0-9]{2})|((02)[\/.]29[\/.](((18|19|20)(04|08|[2468][048]|[13579][26]))|2000))$/;

$(function () {
    $("#DOB").mask("99/99/9999", {
        completed: function () {
            $("#validate-error-info").text('');
            var rawInput = this.val();
            console.info(rawInput);
            if (!dateRegex.test(rawInput)) {
                $("#validate-error-info").text(rawInput + " is not a valid date");
            }
        }
    });
});

有图有真相: