Pregunta

¿Hay alguna manera de verificar si una fecha / hora es válida? Pensaría que sería fácil de verificar:

$date = '0000-00-00';
$time = '00:00:00';
$dateTime = $date . ' ' . $time;

if(strtotime($dateTime)) {
    // why is this valid?
}

lo que realmente me molesta es esto:

echo date('Y-m-d', strtotime($date)); 

da como resultado: " 1999-11-30 " ;,

¿eh? Pasé de 75 a 1999-11-30 ???

Sé que podría hacer una comparación para ver si la fecha es cualquiera de esos valores es igual a la fecha que tengo, pero no es una forma muy robusta de verificar. ¿Hay una buena manera de verificar si tengo una fecha válida? ¿Alguien tiene una buena función para verificar esto?

Editar: La gente pregunta qué estoy ejecutando: Ejecución de PHP 5.2.5 (cli) (construido: 23 de julio de 2008 11:32:27) en Linux localhost 2.6.18-53.1.14.el5 # 1 SMP Wed Mar 5 11:36:49 EST 2008 i686 i686 i386 GNU / Linux

¿Fue útil?

Solución

De php.net

<?php
function isValidDateTime($dateTime)
{
    if (preg_match("/^(\d{4})-(\d{2})-(\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $dateTime, $matches)) {
        if (checkdate($matches[2], $matches[3], $matches[1])) {
            return true;
        }
    }

    return false;
}
?>

Otros consejos

Como se menciona aquí: https://bugs.php.net/bug.php? id = 45647

  

Aquí no hay ningún error, 00-00-00 significa 2000-00-00, que es 1999-12-00,   que es 1999-11-30. Ningún error, perfectamente normal.

Y, como se muestra en algunas pruebas, el comportamiento esperado es retroceder hacia atrás, aunque sea un poco inquietante:

>> date('Y-m-d', strtotime('2012-03-00'))
string: '2012-02-29'
>> date('Y-m-d', strtotime('2012-02-00'))
string: '2012-01-31'
>> date('Y-m-d', strtotime('2012-01-00'))
string: '2011-12-31'
>> date('Y-m-d', strtotime('2012-00-00'))
string: '2011-11-30'
  

fecha de eco ('Y-m-d', strtotime ($ date));

     

da como resultado: " 1999-11-30 "

El resultado de strtotime es 943920000 - este es el número de segundos, aproximadamente, entre época de Unix (base desde la cual se mide el tiempo) hasta 1999-11-30.

Hay un documentado error de mysql en mktime (), localtime (), strtotime () , todos devuelven este valor impar cuando intentas un tiempo pre-epoch (incluido " 0000-00-00 00: 00: 00 "). Hay un debate en el hilo vinculado sobre si esto es realmente un error:

  

Desde que se inició la marca de tiempo desde 1970, no creo que se suponga que   Trabajar de todas formas.

A continuación se muestra una función que utilizo para convertir los tiempos de las fechas, como los anteriores, en una marca de tiempo para las comparaciones, etc., que puede ser de alguna utilidad para usted, para las fechas más allá de " 0000-00-00 00: 00: 00 "

/**
 * Converts strings of the format "YYYY-MM-DD HH:MM:SS" into php dates
 */
function convert_date_string($date_string)
{
    list($date, $time) = explode(" ", $date_string);
    list($hours, $minutes, $seconds) = explode(":", $time);
    list($year, $month, $day) = explode("-", $date);
    return mktime($hours, $minutes, $seconds, $month, $day, $year);
}

No esperes resultados coherentes cuando estés fuera de rango:

cf strtotime

cf Gnu Calendar-date-items .html

  

" Para meses numéricos, la norma ISO 8601   formato & # 8216; año-mes-día & # 8217; esta permitido,   donde año es cualquier número positivo,    mes es un número entre 01   y 12 , y día es un   número entre 01 y 31 . UNA   el cero inicial debe estar presente si una   el número es menor que diez. "

Así que '0000-00-00' da resultados extraños, ¡eso es lógico!


  

" Además, no todos   las plataformas soportan marcas de tiempo negativas,   por lo tanto, su intervalo de fechas puede ser   Limitado a no antes que el Unix.   época . Esto significa que, por ejemplo,   % e,% T,% R y% D (podría haber   más) y fechas anteriores a enero   1, 1970 no funcionará en Windows, algunos   Distribuciones de Linux, y algunos otros   sistemas operativos . "

cf strftime


Use la función checkdate (más robusta):

  

mes:       El mes está comprendido entre 1 y 12 inclusive .

     

día:       El día está dentro del número permitido de días para el dado   mes. Se toman años bisiestos   en consideración.

     

año:       El año es entre 1 y 32767 inclusive .

Esta versión permite que el campo esté vacío, tiene fechas en formato mm / dd / aa o mm / dd / aaaa, permite horas de un solo dígito, agrega am / pm opcional y corrige algunas fallas sutiles en la coincidencia de tiempo .

Todavía permite algunos tiempos patológicos como '23: 14 AM '.

function isValidDateTime($dateTime) {
    if (trim($dateTime) == '') {
        return true;
    }
    if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{2,4})(\s+(([01]?[0-9])|(2[0-3]))(:[0-5][0-9]){0,2}(\s+(am|pm))?)?$/i', $dateTime, $matches)) {
        list($all,$mm,$dd,$year) = $matches;
        if ($year <= 99) {
            $year += 2000;
        }
        return checkdate($mm, $dd, $year);
    }
    return false;
}

Si solo quieres manejar una conversión de fecha sin la hora para un campo de fecha de mysql, puedes modificar este gran código como lo hice yo. En mi versión de PHP sin realizar esta función, obtengo " 0000-00-00 " cada vez. Molesto.

function ConvertDateString ($DateString)
{
    list($year, $month, $day) = explode("-", $DateString);
    return date ("Y-m-d, mktime (0, 0, 0, $month, $day, $year));
}
<?php
function is_valid_date($user_date=false, $valid_date = "1900-01-01") {
    $user_date = date("Y-m-d H:i:s",strtotime($user_date));
    return strtotime($user_date) >= strtotime($valid_date) ? true : false;
}

echo is_valid_date("00-00-00") ? 1 : 0;    // return 0

echo is_valid_date("3/5/2011") ? 1 : 0;    // return 1

Acabo de cambiar la respuesta de Martin, que validará cualquier tipo de fecha y volverá en el formato que desee.

Solo cambia el formato editando debajo de la línea de script strftime (" 10-10-2012 " ;, strtotime ($ dt));

<?php
echo is_date("13/04/10");

function is_date( $str ) {
    $flag = strpos($str, '/');

    if(intval($flag)<=0){
        $stamp = strtotime( $str );
    } else {
        list($d, $m, $y) = explode('/', $str);    
        $stamp = strtotime("$d-$m-$y");
    } 
    //var_dump($stamp) ;

    if (!is_numeric($stamp)) {
        //echo "ho" ;
        return "not a date" ;        
    }

    $month = date( 'n', $stamp ); // use n to get date in correct format
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        $dt = "$year-$month-$day" ;
        return strftime("%d-%b-%Y", strtotime($dt));
        //return TRUE;
    } else {
        return "not a date" ;
    }
}
?>

He utilizado el siguiente código para validar las fechas que provienen de las aplicaciones ExtJS.

function check_sql_date_format($date) {
    $date = substr($date, 0, 10);
    list($year, $month, $day) = explode('-', $date);
    if (!is_numeric($year) || !is_numeric($month) || !is_numeric($day)) {
        return false;
    }
    return checkdate($month, $day, $year);
}
<?php

function is_date( $str ) {
    $stamp = strtotime( $str );

    if (!is_numeric($stamp)) {
        return FALSE;
    }
    $month = date( 'm', $stamp );
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        return TRUE;
    }
    return FALSE;
}
?>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top