正则表达式| 闰年等等

Rio*_*ams 11 javascript regex datetime

我最近一直在寻找一个正则表达式来做一些客户端日期检查,但我找不到一个能满足以下条件的表达式:

  • 范围从1800 - 现在
  • 使用闰年执行正确的日期检查
  • MM/DD/YYYY表格
  • 无效的日期检查

(这些限制超出了我的范围,并且是客户的要求,尽管我努力说服他们这不是最好的路线)

当前代码:

$('input').keyup(function()
{
       var regex = /^(?:(0[1-9]|1[012])[\/.](0[1-9]|[12][0-9]|3[01])[\/.](18|19|20)[0-9]{2})$/;
       $(this).toggleClass('invalid',!regex.test($(this).val()));    
});
Run Code Online (Sandbox Code Playgroud)

更新:

我应该注意,这主要是为了看看这样的正则表达式是否可行(因为在这个问题上使用正则表达式不是我的选择).我知道验证日期的其他(和更好的)选项,但是如前所述 - 这是通过正则表达式查看是否可能.

McK*_*Kay 26

正如其他地方所提到的,正则表达式几乎不是你想要的.但是,话虽如此,如果你真的想要一个正则表达式,下面是它的构建方式:

31个月

(0[13578]|1[02])[\/.](0[1-9]|[12][0-9]|3[01])[\/.](18|19|20)[0-9]{2}
Run Code Online (Sandbox Code Playgroud)

30天的月份

(0[469]|11)[\/.](0[1-9]|[12][0-9]|30)[\/.](18|19|20)[0-9]{2}
Run Code Online (Sandbox Code Playgroud)

2月1 - 8日总是有效的

(02)[\/.](0[1-9]|1[0-9]|2[0-8])[\/.](18|19|20)[0-9]{2}
Run Code Online (Sandbox Code Playgroud)

2月29日也适用于闰年

(02)[\/.]29[\/.](((18|19|20)(04|08|[2468][048]|[13579][26]))|2000)
Run Code Online (Sandbox Code Playgroud)

这意味着如果你把它们放在一起就是这样的:

((0[13578]|1[02])[\/.](0[1-9]|[12][0-9]|3[01])[\/.](18|19|20)[0-9]{2})|((0[469]|11)[\/.](0[1-9]|[12][0-9]|30)[\/.](18|19|20)[0-9]{2})|((02)[\/.](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))
Run Code Online (Sandbox Code Playgroud)

这个版本有点短,但有点难以理解.

((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))
Run Code Online (Sandbox Code Playgroud)

这些脚本很长且不可维护.应该清楚的是,这不是一个好主意,但它是可能的.

注意事项:

  • 范围1800-2099(可以添加更多而没有太大困难,但需要在4-6个不同的地方进行更改)
  • 需要2个数字的月份和日期(严格性可以从~8个地方的表达中删除)
  • [\/.] 作为分隔符(8个地方)
  • 尚未经过测试(我们可以针对所有数字组合进行检查,并与javascript日期函数进行比较?[证明我们正在重新发明轮子])

  • @despot-1800和1900不是leap年。重塑方向盘不是一个好主意的另一个原因是,您可能不了解实际作用力的复杂性。 (2认同)

Jim*_*hel 13

我建议您放弃尝试使用正则表达式.将日期解析为其组成部分(月,日,年)要好得多,然后使用数字比较来确保它在适当的范围内.

更好的是,看看Javascript Date.parse函数是否能达到你想要的效果.

用正则表达式解析日期是可能的,但令人沮丧.很难做到正确,非正则表达式向导难以理解表达(这意味着很难证明事情是正确的),并且与其他选项相比它很.


Šim*_*das 7

我就是这样做的:

function validate( input ) {
    var date = new Date( input );
    input = input.split( '/' );   
    return date.getMonth() + 1 === +input[0] && 
           date.getDate() === +input[1] && 
           date.getFullYear() === +input[2];
}
Run Code Online (Sandbox Code Playgroud)

用法:

validate( '2/1/1983' ) // true
validate( '2/29/1983' ) // false
validate( '2/29/1984' ) // true (1984 is a leap year)
Run Code Online (Sandbox Code Playgroud)

现场演示: http ://jsfiddle.net/9QNRx/