php - usas - Determine correctamente si la cadena de fecha es una fecha válida en ese formato
strip_tags() (14)
Úselo de manera simple con la función precompilada de php:
function checkmydate($date) {
$tempDate = explode(''-'', $date);
// checkdate(month, day, year)
return checkdate($tempDate[1], $tempDate[2], $tempDate[0]);
}
Prueba
checkmydate(''2015-12-01''); //true
checkmydate(''2015-14-04''); //false
Recibo una cadena de fecha de una API y está formateada como yyyy-mm-dd
.
Actualmente estoy usando una expresión regular para validar el formato de cadena, que funciona bien, pero puedo ver algunos casos en los que podría ser un formato correcto según la cadena pero en realidad una fecha no válida. es decir, 2013-13-01
, por ejemplo.
¿Hay alguna forma mejor en PHP para tomar una cadena como 2013-13-01
y decir si es una fecha válida o no para el formato yyyy-mm-dd
?
¿Que tal este?
Simplemente usamos un bloque try-catch.
$dateTime = ''an invalid datetime'';
try {
$dateTimeObject = new DateTime($dateTime);
} catch (Exception $exc) {
echo ''Do something with an invalid DateTime'';
}
Este enfoque no está limitado a un solo formato de fecha / hora, y no necesita definir ninguna función.
Acorde con la respuesta de cl-sah, pero este suena mejor, más corto ...
function checkmydate($date) {
$tempDate = explode(''-'', $date);
return checkdate($tempDate[1], $tempDate[2], $tempDate[0]);
}
Prueba
checkmydate(''2015-12-01'');//true
checkmydate(''2015-14-04'');//false
Determine si alguna cadena es una fecha
function checkIsAValidDate($myDateString){
return (bool)strtotime($myDateString);
}
Esta opción no solo es simple, sino que también acepta casi cualquier formato, aunque con formatos no estándar puede tener errores.
$timestamp = strtotime($date);
return $timestamp ? $date : null;
La forma más fácil de verificar si la fecha dada es válida probablemente la convierta a unixtime usando strtotime
, strtotime
formato de fecha dada y luego comparándola:
function isValidDate($date) { return date(''Ym-d'', strtotime($date)) === $date; }
Por supuesto, puede usar expresiones regulares para verificar la validez, pero estará limitado al formato dado, cada vez que deba editarlo para satisfacer otros formatos, y también será más que necesario. Las funciones incorporadas son la mejor manera (en la mayoría de los casos) para lograr trabajos.
Prueba esto:
$date = "2017-10-01";
function date_checker($input,$devider){
$output = false;
$input = explode($devider, $input);
$year = $input[0];
$month = $input[1];
$day = $input[2];
if (is_numeric($year) && is_numeric($month) && is_numeric($day)) {
if (strlen($year) == 4 && strlen($month) == 2 && strlen($day) == 2) {
$output = true;
}
}
return $output;
}
if (date_checker($date, ''-'')) {
echo "The function is working";
}else {
echo "The function isNOT working";
}
Puede usar la clase DateTime
para este propósito:
function validateDate($date, $format = ''Y-m-d'')
{
$d = DateTime::createFromFormat($format, $date);
// The Y ( 4 digits year ) returns TRUE for any integer with any number of digits so changing the comparison from == to === fixes the issue.
return $d && $d->format($format) === $date;
}
[ Función tomada de esta respuesta . También en php.net . Escrito originalmente por Glavić . ]
Casos de prueba:
var_dump(validateDate(''2013-13-01'')); // false
var_dump(validateDate(''20132-13-01'')); // false
var_dump(validateDate(''2013-11-32'')); // false
var_dump(validateDate(''2012-2-25'')); // false
var_dump(validateDate(''2013-12-01'')); // true
var_dump(validateDate(''1970-12-01'')); // true
var_dump(validateDate(''2012-02-29'')); // true
var_dump(validateDate(''2012'', ''Y'')); // true
var_dump(validateDate(''12012'', ''Y'')); // false
Según la respuesta de Amal Murali,
$d = DateTime::createFromFormat(''Y-m-d g:i:s'', $date);
$d2 = DateTime::createFromFormat(''Y-m-d H:i:s'', $date);
if(($d && $d->format(''Y-m-d g:i:s'') == $date) || ($d2 && $d2->format(''Y-m-d H:i:s'') == $date))
{
return true;
}
else
{
return false;
}
Solución Regex probada:
function isValidDate($date)
{
if (preg_match("/^(((((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)) {
return $date;
}
return null;
}
Esto devolverá nulo si la fecha no es válida o no es el formato aaaa-mm-dd, de lo contrario, devolverá la fecha.
También puede analizar la fecha del mes de la fecha y el año y luego puede usar la función de PHP checkdate()
que puede leer aquí: http://php.net/manual/en/function.checkdate.php
También puedes probar este:
$date="2013-13-01";
if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date))
{
echo ''Date is valid'';
}else{
echo ''Date is invalid'';
}
Tengo esto que, incluso con PHP, me gusta encontrar soluciones funcionales . Entonces, por ejemplo, la respuesta dada por @migli es realmente buena, altamente flexible y elegante.
Pero tiene un problema: ¿y si necesita validar muchas cadenas de DateTime con el mismo formato? Tendría que repetir el formato por todas partes, lo que va en contra del principio DRY . Podríamos poner el formato en una constante, pero aún así, tendríamos que pasar la constante como argumento para cada llamada de función.
¡Pero no temas más! ¡Podemos usar currying para nuestro rescate! PHP no hace esta tarea agradable, pero aún es posible implementar currying con PHP:
<?php
function validateDateTime($format)
{
return function($dateStr) use ($format) {
$date = DateTime::createFromFormat($format, $dateStr);
return $date && $date->format($format) === $dateStr;
};
}
Entonces, ¿qué acabamos de hacer? Básicamente, envolvemos el cuerpo de la función en un anónimo y devolvimos dicha función en su lugar. Podemos llamar a la función de validación de esta manera:
validateDateTime(''Y-m-d H:i:s'')(''2017-02-06 17:07:11''); // true
Sí, no es una gran diferencia ... pero el poder real proviene de la función parcialmente aplicada , que es posible mediante el currying:
// Get a partially applied function
$validate = validateDateTime(''Y-m-d H:i:s'');
// Now you can use it everywhere, without repeating the format!
$validate(''2017-02-06 17:09:31''); // true
$validate(''1999-03-31 07:07:07''); // true
$validate(''13-2-4 3:2:45''); // false
Programación funcional FTW!
Determine si string es una fecha, incluso si string es un formato no estándar
(strtotime no acepta ningún formato personalizado)
<?php
function validateDateTime($dateStr, $format)
{
date_default_timezone_set(''UTC'');
$date = DateTime::createFromFormat($format, $dateStr);
return $date && ($date->format($format) === $dateStr);
}
// These return true
validateDateTime(''2001-03-10 17:16:18'', ''Y-m-d H:i:s'');
validateDateTime(''2001-03-10'', ''Y-m-d'');
validateDateTime(''2001'', ''Y'');
validateDateTime(''Mon'', ''D'');
validateDateTime(''March 10, 2001, 5:16 pm'', ''F j, Y, g:i a'');
validateDateTime(''March 10, 2001, 5:16 pm'', ''F j, Y, g:i a'');
validateDateTime(''03.10.01'', ''m.d.y'');
validateDateTime(''10, 3, 2001'', ''j, n, Y'');
validateDateTime(''20010310'', ''Ymd'');
validateDateTime(''05-16-18, 10-03-01'', ''h-i-s, j-m-y'');
validateDateTime(''Monday 8th of August 2005 03:12:46 PM'', ''l jS /of F Y h:i:s A'');
validateDateTime(''Wed, 25 Sep 2013 15:28:57'', ''D, d M Y H:i:s'');
validateDateTime(''17:03:18 is the time'', ''H:m:s /i/s /t/h/e /t/i/m/e'');
validateDateTime(''17:16:18'', ''H:i:s'');
// These return false
validateDateTime(''2001-03-10 17:16:18'', ''Y-m-D H:i:s'');
validateDateTime(''2001'', ''m'');
validateDateTime(''Mon'', ''D-m-y'');
validateDateTime(''Mon'', ''D-m-y'');
validateDateTime(''2001-13-04'', ''Y-m-d'');
/**** date check is a recursive function. it''s need 3 argument
MONTH,DAY,YEAR. ******/
$always_valid_date = $this->date_check($month,$day,$year);
private function date_check($month,$day,$year){
/** checkdate() is a php function that check a date is valid
or not. if valid date it''s return true else false. **/
$status = checkdate($month,$day,$year);
if($status == true){
$always_valid_date = $year . ''-'' . $month . ''-'' . $day;
return $always_valid_date;
}else{
$day = ($day - 1);
/**recursive call**/
return $this->date_check($month,$day,$year);
}
}