q入正题之前Q我们需要澄清两个概念:

一Q什么是合法的日期范_对于不同的应用场景,q个问题有不同的解释。这里采U?a >MSDN中的U定Q?br />

DateTime 值类型表CD围在公元Q基督纪元)0001 q?1 ?1 日午?12:00:00 到公?(C.E.) 9999 q?12 ?31 日晚?11:59:59 之间的日期和旉?/blockquote>二,关于闰年的阐释?a >人民教育出版Cְ学数学室的解释浅明易懂(mediawiki{都没说明ؓ什?span>整百q䆾必须?00的倍数时才是闰q?/span>Q:
关于公历闰年是这栯定的Q地球绕太阳公{一周叫做一回归q_一回归q长365??8?46U。因此,公历规定有^q和闰年Q^q一q有365日,比回归年?.2422日,四年q0.9688日,故每四年增加一日,q一q有366日,?是闰q。但四年增加一日比四个回归q又?.0312?400q后多3.12?故在400q中设3个闰q?也就是在400q中只设97个闰q_q?样公历年的^均长度与回归q就相近g。由此规定:q䆾是整百数的必L400的倍数才是闰年Q例?900q?100q就不是闰年?/blockquote>清楚了以上两个概念,我们q入正题?br /> 首先需要验证年份,昄Q年份范围ؓ 0001 - 9999Q匹配YYYY的正则表辑ּ为:
[0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3}
其中 [0-9] 也可以表CZؓ \dQ但 \d 不如 [0-9] 直观Q因此下面我一直采?[0-9]

用正则表辑ּ验证日期的难Ҏ二:一是大月份的天数不同Q二是闰q的考虑?br /> 对于W一个难点,我们首先不考虑闰年Q假?月䆾都是28天,q样Q月份和日期可以分成三种情况Q?br />
1、月份ؓ 1, 3, 5, 7, 8, 10, 12Q天数范围ؓ 01 - 31Q匹配MM-DD的正则表辑ּ为:
(0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])
2、月份ؓ 4, 6, 9, 11Q天数范围ؓ 01-30Q匹配MM-DD的正则表辑ּ为:
(0[469]|11)-(0[1-9]|[12][0-9]|30)
3、月份ؓ 2Q考虑q_情况Q匹配MM-DD的正则表辑ּ为:
02-(0[1-9]|[1][0-9]|2[0-8])
Ҏ上面的成果,我们可以得到匚wq_日期格式为YYYY-MM-DD的正则表辑ּQ?br />
([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))

接着我们来解决第二个隄Q闰q的考虑。根据闰q的定义Q我们可以将闰年分ؓ两类Q?br />
1、能?整除但不能被100整除的年份。寻扑֐两位的变化规律,可以很快得到下面的正则匹配:
([0-9]{2})(0[48]|[2468][048]|[13579][26])
2、能?00整除的年份。能?00整除的数肯定能被100整除Q因此后两位肯定?0Q我们只要保证前两位能被4整除卛_Q相应的正则表达式ؓQ?br />
(0[48]|[2468][048]|[3579][26])00
闰年?月䆾?9天,因此匚w闰年日期格式为YYYY-MM-DD的正则表辑ּ为:

(([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29

最后,^q和闰年的日期验证表辑ּ合ƈQ我们得到最l的验证日期格式为YYYY-MM-DD的正则表辑ּ为:

(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)

DD/MM/YYYY格式的正则验证表辑ּ为:

(((0[1-9]|[12][0-9]|3[01])/((0[13578]|1[02]))|((0[1-9]|[12][0-9]|30)/(0[469]|11))|(0[1-9]|[1][0-9]|2[0-8])/(02))/([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3}))|(29/02/(([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00)))