Validación de fechas
El otro día estuve un rato buscando por una expresión regular que validara fechas teniendo en cuenta lógicamente los años bisiestos y despues de casi una hora no fui capaz de encontrarla. Así que me puse manos a la obra y me creé esta expresión regular para validar fechas en formato aaaammdd (sin separadores):
# Comentarios para facilitar la lectura.
# Rango de trabajo 1901.01.01 - 2199.12.31 (sin separadores).
(
# Control de fechas teniendo en cuenta que febrero tiene 28 días.
(19|20|21)[0-9]{2}
(
(
(
# Meses con 31 días: 01-03-05-07-08-10-12.
(0(1|3|5|7|8)|1(0|2))
# Días del 01 al 31
(0[1-9]|[1-2][0-9]|3[0-1])
)
)
|
(
(
# Meses con 30 días: 04-06-09-11.
(0(4|6|9)|11)
# Días del 01 al 30
(0[1-9]|[1-2][0-9]|30)
)
)
|
(
# Meses con 28 días: 02.
02
# Días del 01 al 28
(0[1-9]|1[0-9]|2[0-8])
)
)
)
|
(
# Control de años bisiestos.
# Son bisiestos todos los años divisibles por 4, excluyendo los que
#sean divisibles por 100, pero no los que sean divisibles por 400.
(
# Divisibles por 4, divisibles por 100 y no por 400.
(19|21)
(
(0(4|8))
|
((1|3|5|7|9)(2|6))
|
((2|4|6|8)(0|4|8))
)
|
# Divisibles por 4, divisibles por 100 y también por 400.
20
(
(0(0|4|8))
|
((1|3|5|7|9)(2|6))
|
((2|4|6|8)(0|4|8))
)
)
# mmdd: 0229.
# Todos los años bisiestos o no, tienen en Febrero al menos 28 días
#(controlados en la primera parte de la expresión regular.
# Solo los años bisiestos controlados en esta parte, tienen también
#el día 29 del mes de Febrero.
0229
)
Aquí dejo la expresión regular que valida fechas incluyendo los años bisiestos:
((19|20|21)[0-9]{2}((((0(1|3|5|7|8)|1(0|2))(0[1-9]|[1-2][0-9]|3[0-1])))|(((0(4|6|9)|11)(0[1-9]|[1-2][0-9]|30)))|(02(0[1-9]|1[0-9]|2[0-8]))))|(((19|21)((0(4|8))|((1|3|5|7|9)(2|6))|((2|4|6|8)(0|4|8)))|20((0(0|4|8))|((1|3|5|7|9)(2|6))|((2|4|6|8)(0|4|8))))0229)

