Kriterler:
4'e bölünebilen her yıl, 400'e bölünmediği sürece 100 ile bölünebildiği durumlar dışında artık bir yıldır.
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
Şubatta artık yılda 29 gün ve artık yıl olmadığında 28 gün vardır
Nisan, Haziran, Eylül ve Kasım aylarında 30 gün
Ocak, Mart, Mayıs, Temmuz, Ağustos, Ekim ve Aralık aylarında 31 gün
Ölçek:
Aşağıdaki tarihlerin tümü doğrulamadan geçmelidir:
1976-02-29
2000-02-29
2004-02-29
1999-01-31
Aşağıdaki tarihlerin tümü doğrulamada başarısız olmalıdır:
2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00
Aralık:
1 Ocak 1000'den 31 Aralık 2999'a kadar olan tarihleri test edeceğiz. Teknik olarak şu anda kullanılan Gregoryen takvimi yalnızca 1753'te Britanya İmparatorluğu için ve 1600'lerde çeşitli yıllarda Avrupa ülkeleri için kullanılmaya başlandı, ancak ben bunu yapmayacağım bunun için endişelen.
Artık yılı test etmek için normal ifade:
400 ile bölünebilen yıllar:
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'e bölünebilen yıllar:
[12]\d([02468][048]|[13579][26])
100'e bölünebilen yıllar:
[12]\d00
100'e bölünemez:
[12]\d([1-9]\d|\d[1-9])
Yıllar 100'e bölünebilir ancak 400'e bölünemez:
((1[1345789])|(2[1235679]))00
4'e bölünebilir ancak 100'e bölünemez:
[12]\d([2468][048]|[13579][26]|0[48])
Artık yıllar:
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'e bölünemez:
[12]\d([02468][1235679]|[13579][01345789])
Artık yıl değil:
Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)
Şubat hariç geçerli Ay ve gün (AA-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))
28 günlük Şubat:
02-(0[1-9]|1\d|2[0-8])
29 günlük Şubat:
02-(0[1-9]|[12]\d)
Geçerli tarih:
(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]))))
İşte burada 1 Ocak 1000 ve 31 Aralık 2999 tarihleri için YYYY-AA-GG biçiminde bir normal ifade var.
Biraz kısaltılabileceğinden şüpheleniyorum ama bunu başkasına bırakacağım.
Bu, tüm geçerli tarihlerle eşleşecek. Yalnızca bir tarih içerdiğinde ve başka hiçbir şey içermediğinde geçerli olmasını istiyorsanız, o zaman şu şekilde sarın ^( )$:
^(((((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])))))$
Opsiyonel bir tarih girişi için istiyorsanız (yani boş veya geçerli bir tarih olabilir), o zaman ^$|başlangıca şu şekilde ekleyin :
^$|^(((((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";veya PHP'lerdencheckdate ( int $month , int $day , int $year ).