PHP Regex para verificar la fecha está en formato AAAA-MM-DD

97

Estoy tratando de verificar que las fechas ingresadas por los usuarios finales estén en YYYY-MM-DD. Regex nunca ha sido mi punto fuerte, sigo obteniendo un valor de retorno falso para preg_match () que he configurado.

Así que supongo que he hecho un lío con la expresión regular, que se detalla a continuación.

$date="2012-09-12";

if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
    {
        return true;
    }else{
        return false;
    }

¿Alguna idea?

safari cósmico
fuente
6
Regex no es suficiente para validar una fecha. Después de regex, también debe usar uno de estos dos: date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12";o PHP checkdate ( int $month , int $day , int $year ).
Tiberiu-Ionuț Stan
No estoy tratando de validarlo en este momento, solo quiero asegurarme de que esté en el formato AAAA-MM-DD.
Cosmicsafari
2
Para un valor ingresado por el usuario, ¿qué mejor "punto" en el tiempo para validar que no sea justo después de la expresión regular, en el envío del formulario (para que pueda mostrar un error)?
Tiberiu-Ionuț Stan
Buen punto, podría salvar un hickup más tarde.
Cosmicsafari

Respuestas:

196

Prueba esto.

$date="2012-09-12";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
    return true;
} else {
    return false;
}
Avin Varghese
fuente
18
return (bool)preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date);
Tiberiu-Ionuț Stan
5
¿Por qué se ha marcado esto como la respuesta correcta? Esto devuelve verdadero para una serie de fechas no válidas como 2016-02-30 y 2016-09-31
Graham
7
Esta pregunta trata sobre cómo verificar un formato de fecha (AAAA-MM-DD), y una respuesta marcada como aceptada no siempre es la mejor respuesta, solo significa que funcionó para la persona que preguntó, lea este hermoso recorrido: stackoverflow. com / tour .
stramin
@Graham publicación anterior Lo sé, pero estoy de acuerdo con Stramin: esta pregunta se refiere a la validación del formato, no a la validación de la fecha real
treyBake
98

Probablemente sea mejor usar otro mecanismo para esto.

La solución moderna, con DateTime:

$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());

Esto también valida la entrada: $dt !== falseasegura que la fecha se pueda analizar con el formato especificado y el array_sumtruco es una forma concisa de asegurar que PHP no hizo "cambios de mes" (por ejemplo, considere que el 32 de enero es el 1 de febrero). Consulte DateTime::getLastErrors()para obtener más información.

Solución de la vieja escuela con explodey checkdate:

list($y, $m, $d) = array_pad(explode('-', $date, 3), 3, 0);
return ctype_digit("$y$m$d") && checkdate($m, $d, $y);

Esto valida que la entrada también sea una fecha válida. Puede hacer eso con una expresión regular, por supuesto, pero será más complicado, y el 29 de febrero no se puede validar con una expresión regular en absoluto.

El inconveniente de este enfoque es que hay que tener mucho cuidado de rechazar todas las posibles entradas "malas" sin emitir un aviso bajo ninguna circunstancia. Así es cómo:

  • explodeestá limitado a devolver 3 tokens (de modo que si la entrada es "1-2-3-4", $dse convertirá en "3-4")
  • ctype_digit se utiliza para asegurarse de que la entrada no contenga ningún carácter no numérico (aparte de los guiones)
  • array_padse utiliza (con un valor predeterminado que hará checkdateque falle) para asegurarse de que se devuelvan suficientes elementos para que si la entrada es "1-2" list()no se emita un aviso
Jon
fuente
+1, siempre usado DateTimey nunca escuché sobre checkdate... lástima de mí.
k102
@ k102: DateTimetambién puede hacer esto. Acabo de terminar de dar cuerpo a la respuesta, échale un vistazo de nuevo si quieres.
Jon
Mirando el manual de PHP, parece que la primera solución validará las fechas incompletas (completando los valores faltantes de la fecha actual).
usuario2428118
Otro problema con la solución # 1: "los valores no existentes se traspasan", por ejemplo, 2001-02-31 se convierte en 2001-03-03. (Aunque el OP no ha pedido explícitamente que esto no sea posible).
user2428118
1
@ user2428118: ¿Probaste la solución n. ° 1 exactamente como se indica o solo en la primera línea? ¿Hiciste clic en el enlace que le doy a la documentación getLastErrors?
Jon
42

aaaa-mm-dd: /^((((19|[2-9]\d)\d{2})\-(0[13578]|1[02])\-(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\-(0[13456789]|1[012])\-(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\-02\-(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\-02\-29))$/g

aaaa / mm / dd: /^((((19|[2-9]\d)\d{2})\/(0[13578]|1[02])\/(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\/(0[13456789]|1[012])\/(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\/02\/(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\/02\/29))$/g

mm-dd-aaaa: /^(((0[13578]|1[02])\-(0[1-9]|[12]\d|3[01])\-((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\-(0[1-9]|[12]\d|30)\-((19|[2-9]\d)\d{2}))|(02\-(0[1-9]|1\d|2[0-8])\-((19|[2-9]\d)\d{2}))|(02\-29\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

mm / dd / aaaa: /^(((0[13578]|1[02])\/(0[1-9]|[12]\d|3[01])\/((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\/(0[1-9]|[12]\d|30)\/((19|[2-9]\d)\d{2}))|(02\/(0[1-9]|1\d|2[0-8])\/((19|[2-9]\d)\d{2}))|(02\/29\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

dd / mm / aaaa: /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

dd-mm-aaaa: /^(((0[1-9]|[12]\d|3[01])\-(0[13578]|1[02])\-((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\-(0[13456789]|1[012])\-((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\-02\-((19|[2-9]\d)\d{2}))|(29\-02\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

Shyju KP
fuente
Todo lo anterior funciona para fechas de 1900 a 9999, que es lo que se necesita la mayor parte del tiempo y es 74 caracteres más corto que mi intento (en el formato aaaa-mm-dd). si desea fechas anteriores a 1900, entonces un pequeño ajuste a la respuesta de Shyju permitirá desde el año 1000 y es otros 23 caracteres más cortos: ^ ((([1-9] \ d {3}) \ - (0 [13578] | 1 [02]) \ - (0 [1-9] | [12] \ d | 3 [01])) | (((19 | [2-9] \ d) \ d {2}) \ - ( 0 [13456789] | 1 [012]) \ - (0 [1-9] | [12] \ d | 30)) | (([1-9] \ d {3}) \ - 02 \ - (0 [1-9] | 1 \ d | 2 [0-8])) | (([1-9] \ d (0 [48] | [2468] [048] | [13579] [26]) | ( (16 | [2468] [048] | [3579] [26]) 00)) \ - 02 \ -29)) $
Graham
36

Criterios:

Cada año divisible por 4 es un año bisiesto, excepto cuando es divisible por 100 a menos que sea divisible por 400. Entonces:

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

Febrero tiene 29 días en un año bisiesto y 28 cuando no es un año bisiesto

30 días en abril, junio, septiembre y noviembre

31 días en enero, marzo, mayo, julio, agosto, octubre y diciembre

Prueba:

Las siguientes fechas deben pasar la validación:

1976-02-29
2000-02-29
2004-02-29
1999-01-31

Las siguientes fechas deberían fallar en la validación:

2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00

Rango:

Probaremos fechas desde el 1 de enero de 1000 hasta el 31 de diciembre de 2999. Técnicamente, el calendario gregoriano que se usa actualmente solo entró en uso en 1753 para el Imperio Británico y en varios años en el siglo XVII para países de Europa, pero no voy a preocuparse por eso.

Regex para probar durante un año bisiesto:

Los años divisibles por 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

Los años divisibles por 4:

[12]\d([02468][048]|[13579][26])

Los años divisibles por 100:

[12]\d00

No divisible por 100:

[12]\d([1-9]\d|\d[1-9])

Los años divisibles por 100 pero no por 400:

((1[1345789])|(2[1235679]))00

Divisible por 4 pero no por 100:

[12]\d([2468][048]|[13579][26]|0[48])

Los años bisiestos:

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])

No divisible por 4:

[12]\d([02468][1235679]|[13579][01345789])

No es un año bisiesto:

Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)

Mes y día válidos excepto febrero (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))

Febrero con 28 días:

02-(0[1-9]|1\d|2[0-8])

Febrero con 29 días:

02-(0[1-9]|[12]\d)

Fecha válida:

(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]))))

Ahí lo tiene una expresión regular para las fechas entre el 1 de enero de 1000 y el 31 de diciembre de 2999 en formato AAAA-MM-DD.

Sospecho que se puede acortar un poco, pero se lo dejo a otra persona.

Eso coincidirá con todas las fechas válidas. Si desea que solo sea válido cuando contenga solo una fecha y nada más, envuélvalo ^( )$así:

^(((((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])))))$

Si lo desea para una entrada de fecha opcional (es decir, puede estar en blanco o una fecha válida), agregue ^$|al principio, así:

^$|^(((((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])))))$
Graham
fuente
7
Esa es una expresión heroica y muy bien explicada.
ambiente
¿Tiene pruebas sólidas de que aprobará todos los casos válidos y fallará en todos los casos inválidos?
Md Ashraful Islam
@Md Ashraful Islam No
Graham
@Graham Aunque no hay problema, lo estamos usando en nuestro sitio web. Espero que no ocurra ningún problema.
Md Ashraful Islam
@Md Ashraful Islam - También lo usamos y no hemos tenido ningún problema con él hasta ahora
Graham
18

Puedes hacerlo de esta manera:

if (preg_match("/\d{4}\-\d{2}-\d{2}/", $date)) {
    echo 'true';
} else {
    echo 'false';
}

pero será mejor que uses este:

$date = DateTime::createFromFormat('Y-m-d', $date);
if ($date) {
    echo $date -> format('Y-m-d');
}

en este caso, obtendrá un objeto que es mucho más fácil de usar que solo cadenas.

k102
fuente
1
La técnica de fecha
hora
Este no es un buen ejemplo, especialmente si desea obtener una fecha (Ymd). Ejemplo: 0175-44-19927pasará.
Attila Naghi
7

Sé que esta es una vieja pregunta. Pero creo que tengo una buena solución.

$date = "2016-02-21";
$format = "Y-m-d";

if(date($format, strtotime($date)) == date($date)) {
    echo "true";
} else {
    echo "false";
}

Puedes probarlo. Si cambia la fecha al 21.02.2016, el eco es falso. Y si cambia el formato después de eso a dmY, el eco es verdadero.

Con este código fácil, debería poder verificar qué formato de fecha se usa sin verificarlo con la expresión regular.

Quizás haya una persona que lo pruebe en cada caso. Pero creo que mi idea es válida en general. A mi me parece lógico.

Micha93
fuente
No creo que necesite date () alrededor de $ date en la línea if. if (date ($ format, strtotime ($ date)) == $ date) - debería ser suficiente
iateadonut
7

Puede usar preg_match con una función php checkdate

$date  = "2012-10-05";
$split = array();
if (preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $split))
{
    return checkdate($split[2], $split[3], $split[1]);
}

return false;
Jonathan Muller
fuente
return preg_match ("/ ^ ([0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) $ /", $ fecha, $ división)) && fecha de verificación ($ split [2], $ split [3], $ split [1]);
Tiberiu-Ionuț Stan
5

preg_match necesita un / u otro carácter como delimitador.

preg_match("/^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$/",$date)

también debe verificar la validez de esa fecha para que no termine con algo como 9999-19-38

bool checkdate ( int $month , int $day , int $year )
marianboda
fuente
3

También puedes hacerlo así:

if (DateTime::createFromFormat('Y-m-d', $date)->format('Y-m-d') === $date) {

    // date is correctly formatted and valid, execute some code

}

Esto no solo verificará el formato, sino también la validez de la fecha propia, ya DateTimeque solo creará fechas válidas y esto debe coincidir con la entrada.

Kasimir
fuente
3

puedes usar

function validateDate($date, $format = 'Y-m-d H:i:s')
{
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

$date="2012-09-12";    
echo validateDate($date, 'Y-m-d'); // true or false
Jack
fuente
2

Verificar y validar la YYYY-MM-DDfecha en una declaración de línea

function isValidDate($date) {
    return preg_match("/^(\d{4})-(\d{1,2})-(\d{1,2})$/", $date, $m)
        ? checkdate(intval($m[2]), intval($m[3]), intval($m[1]))
        : false;
}

La salida será:

var_dump(isValidDate("2018-01-01")); // bool(true)
var_dump(isValidDate("2018-1-1"));   // bool(true)
var_dump(isValidDate("2018-02-28")); // bool(true)
var_dump(isValidDate("2018-02-30")); // bool(false)

Se permiten el día y el mes sin cero a la izquierda. Si no desea permitir esto, la expresión regular debería ser:

"/^(\d{4})-(\d{2})-(\d{2})$/"
Vladislav Savchuk
fuente
1

Si desea hacer coincidir ese tipo de fecha, use:

preg_match("~^\d{4}-\d{2}-\d{2}$~", $date)
ujovlado
fuente
1

Esto debería decirle si el formato es válido y si la fecha de entrada es válida.

    $datein = '2012-11-0';

    if(preg_match('/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/', $datein)){
        echo 'good';
    }else{
        echo 'no good';
    }
Kenzo
fuente
1

Si es de alguna ayuda, aquí hay una expresión regular para el formato jnY (el año debe ser mayor que 2018):

if (preg_match('/^([1-9]|[1-2][0-9]|[3][0-1])\-([1-9]|[1][0-2])\-(?:20)([1][8-9]|[2-9][0-9])$/', $date)) {
   // Do stuff
}
Filip
fuente
1

Formato 1: $ format1 = "2012-12-31";

Formato 2: $ formato2 = "31-12-2012";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$format1)) {
    return true;
} else {
    return false;
}

if (preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-[0-9]{4}$/",$format2)) {
    return true;
} else {
    return false;
}
Hasib Kamal
fuente
1

Probablemente útil para alguien:

$patterns = array(
            'Y'           =>'/^[0-9]{4}$/',
            'Y-m'         =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])$/',
            'Y-m-d'       =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$/',
            'Y-m-d H'     =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4])$/',
            'Y-m-d H:i'   =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?(0|[0-5][0-9]|60)$/',
            'Y-m-d H:i:s' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?((0|[0-5][0-9]):?(0|[0-5][0-9])|6000|60:00)$/',
        );
echo preg_match($patterns['Y'], '1996'); // true
echo preg_match($patterns['Y'], '19966'); // false
echo preg_match($patterns['Y'], '199z'); // false
echo preg_match($patterns['Y-m'], '1996-0'); // false
echo preg_match($patterns['Y-m'], '1996-09'); // true
echo preg_match($patterns['Y-m'], '1996-1'); // true
echo preg_match($patterns['Y-m'], '1996/1'); // true
echo preg_match($patterns['Y-m'], '1996/12'); // true
echo preg_match($patterns['Y-m'], '1996/13'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-1'); // true
echo preg_match($patterns['Y-m-d'], '1996-11-0'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-32'); // false
echo preg_match($patterns['Y-m-d H'], '1996-11-31 0'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 00'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 24'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 25'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 2400'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:00'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:59'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:60'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:6000'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:00'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:59'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:60'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:01'); // false
el manh Nguyen
fuente
'1996-11-31 24:00'); // true, ¿De Verdad? Además, a veces hay 61 segundos en un minuto, ver: en.wikipedia.org/wiki/Leap_second
Toto
1

Función para validar formato de fecha genérico:

function validateDate($date, $format = 'Y-m-d') {
  $d = DateTime::createFromFormat($format, $date);
  return $d && $d->format($format) == $date;
}

Ejemplo de ejecución:

var_dump(validateDate('2021-02-28')); // true
var_dump(validateDate('2021-02-29')); // false
Sharad Pawar
fuente
Por favor, ponga su respuesta siempre en contexto en lugar de simplemente pegar el código. Consulte aquí para obtener más detalles. Edite también su respuesta para que contenga todas las partes del código en el bloque de
rebajas
0

Todo depende de cuán estricta quieras que sea esta función. Por ejemplo, si no desea permitir meses por encima de 12 y días por encima de 31 (sin depender del mes, eso requeriría escribir una lógica de fecha), podría volverse bastante complicado:

function checkDate($date)
{
  $regex = '/^' . 
    '(' .

    // Allows years 0000-9999
    '(?:[0-9]{4})' .
    '\-' .

    // Allows 01-12
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)' .
    ')' .
    '\-' .

    // Allows 01-31
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)|(?:13)|(?:14)|(?:15)|(?:16)|(?:17)|(?:18)|(?:19)|(?:20)|' .
    '(?:21)|(?:22)|(?:23)|(?:24)|(?:25)|(?:26)|(?:27)|(?:28)|(?:29)|(?:30)|' .
    '(?:31)' .
    ')' .

    '$/';

  if ( preg_match($regex, $date) ) {
    return true;
  }

  return false;
}

$result = checkDate('2012-09-12');

Personalmente, solo iría por: /^([0-9]{4}\-([0-9]{2}\-[0-9]{2})$/

Ariaan
fuente
4
Esta expresión regular es innecesariamente complicada. 0[1-9]|1[0-2]coincide con el mes 01-12 y 0[1-9]|[12][0-9]|3[01]coincide con el día 01-31.
estrar
Disculpe mientras vomito
AlxVallejo
0

Para trabajar con fechas en php, debe seguir el estándar php para que la expresión regular dada le asegure que tiene una fecha válida que pueda operar con PHP.

    preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)
Pratik Soni
fuente
Su rgex es incorrecto, no coincidirá 1980-01-01pero coincidirá2100-02-29
Toto
0

Este método puede ser útil para validar la fecha en PHP. El método actual es para el formato mm / dd / aaaa. Debe actualizar la secuencia de parámetros en la fecha de verificación según su formato y delimitador en explosión .

    function isValidDate($dt)
    {
        $dtArr = explode('/', $dt);
        if (!empty($dtArr[0]) && !empty($dtArr[1]) && !empty($dtArr[2])) {
            return checkdate((int) $dtArr[0], (int) $dtArr[1], (int) $dtArr[2]);
        } else {
            return false;
        }
    }
Amit Garg
fuente
0

[Si usa Symfony 4.1.2, intente esto] [1]

  $validDate = explode("-",$request->get('date'));
        if (checkdate(filter_var($validDate[1],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[0],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[2],FILTER_SANITIZE_NUMBER_INT))){
            $date = date_create(filter_var($request->get('date'),FILTER_SANITIZE_SPECIAL_CHARS));
        }else{
            return $this->redirectToRoute('YOUR_ROUTE');
        }
HIZO B
fuente
0

Desde Laravel 5.7 y formato de fecha, es decir: 31/12/2019

function checkDateFormat(string $date): bool
{
    return preg_match("/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/[0-9]{4}$/", $date);
}
Mexidense
fuente
0

Estaba buscando "cómo validar la fecha" y encontré esta solución. Es antiguo, pero compartiré el siguiente método que se puede usar para validar la fecha en php.

checkdate('01', '31', '2019')
Parvez Alam
fuente