2008-09-26 13 views
13

¿Hay una manera de comprobar para ver si una fecha/hora es válido se podría pensar estos serían fácil de comprobar:cheque php para una fecha válida, conversiones de fecha extraños

lo que realmente me pone es esto:

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

resultados en: "1999-11-30",

eh? fui de 0000-00-00 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 se pregunta lo que estoy ejecutando: PHP 5.2.5 Ejecución (CLI) (construida: Jul 23 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

+0

¿qué versión de PHP es esto? – Swati

+0

Pruebe esto: http://php.net/manual/en/function.checkdate.php –

+0

strtotime ("0000-00-00 00:00:00") devuelve FALSE en un sistema de 32 bits. \t strtotime ("0000-00-00 00:00:00") devuelve -62169955200 en un sistema de 64 bits. –

Respuesta

22

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; 
} 
?> 
2

echo date ('Ym-d', strtotime ($ date));

resultados en: "1999-11-30"

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

Hay una documentado mysql bug sobre todo mktime(), localtime(), strtotime() devolver este valor impar cuando intenta un tiempo pre-época (incluyendo "0000-00-00 00:00:00"). Hay un poco de debate sobre el hilo vinculadas en cuanto a si este es en realidad un error:

Desde la marca de tiempo se pone en marcha a partir de 1970, no creo que supone que el trabajo en de todos modos.

A continuación se muestra una función que utilizo para convertir datetimes como el anterior a una marca de tiempo para las comparaciones, etc, que pueden ser de alguna utilidad para usted, para fechas más allá "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); 
} 
+0

intenté la fecha ('Ym-d', convert_date_string ('0000-00-00 00:00:00')) pero todavía aparece la fecha de 1999 – SeanDowney

+0

Encontré el informe de error de PHP sobre el comportamiento impar de las funciones basadas en tiempo en PHP para el valor 0000-00 .. Existe cierto debate sobre ese hilo en cuanto a si realmente es un error, ¡como si la gente alguna vez quisiera calcular una fecha anterior a 1970! – ConroyP

+0

No es un error: https://bugs.php.net/bug.php?id=45647 – Izkata

1

no hay que esperar resultados coherentes cuando se está fuera de rango:

CF strtotime

cf Gnu Calendar-date-items .html

"Durante meses numéricos, el formato ISO 8601 se permite 'año-mes-día', donde el año es cualquier número positivo, meses es una número entre 01 y 12, y día es un número entre 01 y 31.Un cero inicial debe incluir necesariamente un número es inferior a diez. "

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


" Además, no todas las plataformas admiten marcas de tiempo negativas, por lo tanto, su intervalo de fechas puede ser limitado a no anterior a Unix época. Esto significa que, p. % e,% T,% R y% D (no podría ser más) y fechas anteriores a Jan 1, 1970 no funcionará en Windows, algunas distribuciones de Linux, y algunos otros sistemas operativos ".

cf strftime


uso checkdate función en lugar (más robusto):

mes: El mes es entre 1 y 12 inclusive.

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

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

1

Si solo desea manejar una conversión de fecha sin el tiempo para un campo de fecha mysql, puede modificar este gran código como yo lo hice. En mi versión de PHP sin realizar esta función obtengo "0000-00-00" todo el tiempo. Molesto.

function ConvertDateString ($DateString) 
{ 
    list($year, $month, $day) = explode("-", $DateString); 
    return date ("Y-m-d, mktime (0, 0, 0, $month, $day, $year)); 
} 
1

Esta versión permite que el campo esté vacío, tiene fechas en/dd/formato aa o dd/mm/aaaa mm, permiten horas de un solo dígito, añade la mañana opcional/h, y corrige algunos defectos sutiles en el tiempo partido

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; 
} 
-1
<?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; 
} 
?> 
+1

Esto no funciona con algunos casos extremos como el 31 de febrero o el 31 de abril. Por ejemplo, la fecha ("Y-m-d", strtotime ("31.2.2012")) da como resultado "2012-03-02", que pasa la validación del checkdate aunque el usuario no haya ingresado una fecha válida. –

0

que han sido simplemente cambiando el martin respuesta anterior, que validará cualquier tipo de fecha y volver en el formato que desee.

Simplemente cambie 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" ; 
    } 
} 
?> 
0
<?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 
+1

que funcionaría para las fechas que son "recientes", pero si tengo una fecha en los primeros noventa siempre devolvería falso – SeanDowney

+0

@SeanDowney editado, que debería devolver VERDADERO para su "fecha en los primeros noventa". – Josue

5

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

No hay error aquí, significa 00-00-00 2000-00-00, que es 1999-12-00, que es 1999-11-30. Sin errores, perfectamente normal.

Y como se muestra con unas cuantas pruebas, rodando hacia atrás es el comportamiento esperado, aunque 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' 
+0

¡Yikes! eso es un poco loco, pero es bueno estar al tanto de – SeanDowney

0

He utilizado el siguiente código para validar fechas procedentes de 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); 
}