เกณฑ์:
ทุกๆปีหารด้วย 4 เป็นปีอธิกสุรทินยกเว้นเมื่อหารด้วย 100 ลงตัวเว้นแต่จะหารด้วย 400 ดังนั้น:
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
กุมภาพันธ์มี 29 วันในปีอธิกสุรทินและ 28 วันเมื่อไม่ใช่ปีอธิกสุรทิน
30 วันในเดือนเมษายนมิถุนายนกันยายนและพฤศจิกายน
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
พิสัย:
เราจะทดสอบวันที่ตั้งแต่ 1 มกราคม 1000 ถึง 31 ธันวาคม 2999 ใน ทางเทคนิคแล้วปฏิทินเกรกอเรียนที่ใช้ในปัจจุบันเริ่มใช้เฉพาะในปี 1753 สำหรับจักรวรรดิอังกฤษและในปี 1600 สำหรับประเทศต่างๆในยุโรป แต่ฉันจะไม่ กังวลเกี่ยวกับเรื่องนั้น
Regex เพื่อทดสอบปีอธิกสุรทิน:
ปีหารด้วย 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)
เดือนและวันที่ถูกต้องไม่รวมกุมภาพันธ์ (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))
กุมภาพันธ์มี 28 วัน:
02-(0[1-9]|1\d|2[0-8])
กุมภาพันธ์ 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]))))
ดังนั้นคุณจึงมี regex สำหรับวันที่ระหว่าง 1 มกราคม 1000 ถึง 31 ธันวาคม 2999 ในรูปแบบ YYYY-MM-DD
ฉันสงสัยว่ามันอาจจะสั้นลงไปหน่อย แต่ฉันจะปล่อยให้คนอื่นไป
ซึ่งจะตรงกับวันที่ที่ถูกต้องทั้งหมด หากคุณต้องการให้ใช้งานได้ก็ต่อเมื่อมีวันที่เพียงวันเดียวและไม่มีสิ่งอื่นใดให้ห่อไว้^( )$
ดังนี้:
^(((((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";
หรือของcheckdate ( int $month , int $day , int $year )
PHP