Kriteria:
Setiap tahun habis dibagi 4 adalah tahun kabisat, kecuali jika habis habis 100 kecuali habis habis 400. Jadi:
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
Februari memiliki 29 hari sebagai tahun kabisat dan 28 hari sebagai tahun kabisat
30 hari pada bulan April, Juni, September dan November
31 hari di bulan Januari, Maret, Mei, Juli, Agustus, Oktober dan Desember
Uji:
Semua tanggal berikut harus lulus validasi:
1976-02-29
2000-02-29
2004-02-29
1999-01-31
Tanggal-tanggal berikut ini harusnya semua gagal validasi:
2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00
Jarak:
Kami akan menguji untuk tanggal dari 1 Jan 1000 hingga 31 Des 2999. Secara teknis, kalender Gregorian yang saat ini digunakan hanya mulai digunakan pada 1753 untuk Kerajaan Inggris dan pada berbagai tahun pada 1600-an untuk negara-negara di Eropa, tetapi saya tidak akan melakukannya khawatir tentang itu.
Regex untuk menguji tahun kabisat:
Tahun-tahun yang habis dibagi 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
Tahun-tahun yang habis dibagi 4:
[12]\d([02468][048]|[13579][26])
Tahun-tahun yang habis dibagi 100:
[12]\d00
Tidak habis dibagi 100:
[12]\d([1-9]\d|\d[1-9])
Tahun-tahun yang habis dibagi 100 tetapi tidak habis dibagi 400:
((1[1345789])|(2[1235679]))00
Dapat dibagi 4 tetapi tidak dibagi 100:
[12]\d([2468][048]|[13579][26]|0[48])
Tahun kabisat:
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])
Tidak habis dibagi 4:
[12]\d([02468][1235679]|[13579][01345789])
Bukan tahun kabisat:
Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)
Bulan dan hari yang valid kecuali Februari (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))
Februari dengan 28 hari:
02-(0[1-9]|1\d|2[0-8])
Februari dengan 29 hari:
02-(0[1-9]|[12]\d)
Tanggal berlaku:
(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]))))
Jadi begitulah regex untuk tanggal antara 1 Jan 1000 dan 31 Des 2999 dalam format YYYY-MM-DD.
Saya kira ini bisa dipersingkat, tapi saya serahkan pada orang lain.
Itu akan cocok dengan semua tanggal yang valid. Jika Anda ingin itu hanya berlaku ketika itu hanya berisi satu tanggal dan tidak ada yang lain, maka bungkuslah ^( )$
seperti ini:
^(((((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])))))$
Jika Anda menginginkannya untuk entri tanggal opsional (misalnya dapat dikosongkan atau tanggal yang valid) kemudian tambahkan ^$|
di awal, seperti ini:
^$|^(((((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";
atau PHPcheckdate ( int $month , int $day , int $year )
.