Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
311 views
in Technique[技术] by (71.8m points)

javascript - Regular Expression | Leap Years and More

I've recently been looking for a regular expression to do some client side date checking, and I haven't been able to find one that can satisfy the following criteria:

  • Has a range from 1800 - Now
  • Performs proper date checking with leap years
  • MM/DD/YYYY Form
  • Invalid Date Checking

(These constraints were outside of my scope and are a requirement as per the client, despite my efforts to convince them this wasn't the best route)

Current code:

$('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()));    
});

Update:

I should note that this is primarily to see if a regular expression like this would be possible (as the use of a Regex is not my choice in this matter). I am aware of the other (and better) options for validating a date, however as previously mentioned - this is to see if it was possible through a regular expression.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As is mentioned elsewhere, regular expressions almost certanily not what you want. But, having said that, if you really want a regular expression, here is how it is built:

31 day months

(0[13578]|1[02])[/.](0[1-9]|[12][0-9]|3[01])[/.](18|19|20)[0-9]{2}

30 day months

(0[469]|11)[/.](0[1-9]|[12][0-9]|30)[/.](18|19|20)[0-9]{2}

February 1-28 always valid

(02)[/.](0[1-9]|1[0-9]|2[0-8])[/.](18|19|20)[0-9]{2}

February 29 also valid on leap years

(02)[/.]29[/.](((18|19|20)(04|08|[2468][048]|[13579][26]))|2000)

which means it would be this if you put it all together:

((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))

This version is a little shorter, but a little harder to understand.

((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))

These scripts are long and unmaintainable. It should be clear that this isn't a good idea, but it is possible.

Caveats:

  • range 1800-2099 (more can be added without too much difficulty, but requires changes in 4-6 disparate places)
  • requires 2 digit months and days (the strictness could be removed from the expression in ~8 places)
  • [/.] as seperators (8 places)
  • Hasn't been tested (we could check it against all digit combinations and compare with the javascript date function? [proof that we're reinventing the wheel])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...