基準:
400で割り切れない場合を除いて、100で割り切れない場合を除いて、毎年4で割り切れる年はうるう年です。
2004 - leap year - divisible by 4
1900 - not a leap year - divisible by 4, but also divisible by 100
2000 - leap year - divisible by 4, also divisible by 100, but divisible by 400
2月のうるう年は29日、うるう年でない場合は28日
4月、6月、9月、11月の30日
1月、3月、5月、7月、8月、10月、12月の31日
テスト:
次の日付はすべて検証に合格する必要があります。
1976-02-29
2000-02-29
2004-02-29
1999-01-31
次の日付はすべて検証に失敗します。
2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00
範囲:
1000年1月1日から2999年12月31日までの日付をテストします。 技術的には、現在使用されているグレゴリオ暦は1753年に大英帝国でのみ使用され、1600年代にはヨーロッパの国々で使用されましたが、心配してください。
うるう年をテストする正規表現:
400で割り切れる年:
1200|1600|2000|2400|2800
can be shortened to:
(1[26]|2[048])00
if you wanted all years from 1AD to 9999 then this would do it:
(0[48]|[13579][26]|[2468][048])00
if you're happy with accepting 0000 as a valid year then it can be shortened:
([13579][26]|[02468][048])00
4で割り切れる年
[12]\d([02468][048]|[13579][26])
100で割り切れる年:
[12]\d00
100で割り切れない場合:
[12]\d([1-9]\d|\d[1-9])
年は100で割り切れますが、400では割り切れません。
((1[1345789])|(2[1235679]))00
4で割り切れますが、100では割り切れません。
[12]\d([2468][048]|[13579][26]|0[48])
うるう年:
divisible by 400 or (divisible by 4 and not divisible by 100)
((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48])
4で割り切れない:
[12]\d([02468][1235679]|[13579][01345789])
うるう年ではない:
Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)
2月を除く有効な月日(MM-DD):
((01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|((04|06|09|11)-(0[1-9]|[12]\d|30))
shortened to:
((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30))
2月、28日あり:
02-(0[1-9]|1\d|2[0-8])
2月29日:
02-(0[1-9]|[12]\d)
有効日:
(leap year followed by (valid month-day-excluding-february OR 29-day-february))
OR
(non leap year followed by (valid month-day-excluding-february OR 28-day-february))
((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8]))))
したがって、YYYY-MM-DD形式の1000年1月1日から2999年12月31日までの日付の正規表現があります。
かなり短縮できると思いますが、他の人にお任せします。
それはすべての有効な日付と一致します。日付が1つだけで、それ以外は何も含まない場合にのみ有効にする場合は、次の^( )$
ようにラップします。
^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$
オプションの日付エントリ(つまり、空白または有効な日付)に必要な場合^$|
は、次のように先頭に追加します。
^$|^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$
date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12";
またはPHPcheckdate ( int $month , int $day , int $year )
。