Criteri:
Ogni anno divisibile per 4 è un anno bisestile, tranne quando è divisibile per 100 a meno che non sia divisibile per 400. Quindi:
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
Febbraio ha 29 giorni in un anno bisestile e 28 quando non è un anno bisestile
30 giorni in aprile, giugno, settembre e novembre
31 giorni in gennaio, marzo, maggio, luglio, agosto, ottobre e dicembre
Test:
Le seguenti date dovrebbero tutte superare la convalida:
1976-02-29
2000-02-29
2004-02-29
1999-01-31
Le seguenti date dovrebbero non superare la convalida:
2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00
Gamma:
Verificheremo le date dal 1 ° gennaio 1000 al 31 dicembre 2999. Tecnicamente il calendario gregoriano attualmente utilizzato è entrato in uso solo nel 1753 per l'Impero britannico e in vari anni nel 1600 per i paesi in Europa, ma non ho intenzione di farlo preoccuparti di questo.
Regex da testare per un anno bisestile:
Gli anni divisibili per 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
Gli anni divisibili per 4:
[12]\d([02468][048]|[13579][26])
Gli anni divisibili per 100:
[12]\d00
Non divisibile per 100:
[12]\d([1-9]\d|\d[1-9])
Gli anni divisibili per 100 ma non per 400:
((1[1345789])|(2[1235679]))00
Divisibile per 4 ma non per 100:
[12]\d([2468][048]|[13579][26]|0[48])
Gli anni bisestili:
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])
Non divisibile per 4:
[12]\d([02468][1235679]|[13579][01345789])
Non è un anno bisestile:
Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)
Mese e giorno validi escluso febbraio (MM-GG):
((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))
Febbraio con 28 giorni:
02-(0[1-9]|1\d|2[0-8])
Febbraio con 29 giorni:
02-(0[1-9]|[12]\d)
Data valida:
(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]))))
Quindi ecco una regex per le date tra il 1 ° gennaio 1000 e il 31 dicembre 2999 nel formato AAAA-MM-GG.
Sospetto che possa essere accorciato un po ', ma lo lascerò a qualcun altro.
Ciò corrisponderà a tutte le date valide. Se vuoi che sia valido solo quando contiene solo una data e nient'altro, inseriscilo in questo ^( )$
modo:
^(((((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])))))$
Se lo desideri per una voce di data facoltativa (ad es. Può essere vuoto o una data valida), aggiungi ^$|
all'inizio, in questo modo:
^$|^(((((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";
o PHPcheckdate ( int $month , int $day , int $year )
.