2009-02-28 31 views
8

Los usuarios seleccionarían su fecha de 3 desplegables (día, mes, año). Los combinaré en el lado del servidor para hacer una cadena como '2008-12-30'. ¿Cómo puedo validar para asegurarme de que esta fecha esté en el formato/numérico correcto solamente, etc.?Cómo validar una fecha MYSQL en PHP?

+0

Puede reformular esto ligeramente; no está del todo claro lo que estás buscando. ¿Desea validar la fecha proveniente de la consulta, o desea validar los componentes individuales antes de insertarlos en la base de datos? – Rob

+0

Quiero combinar los componentes de la fecha y validar la fecha combinada con la base de datos. –

+1

¿Por qué se bajó este valor? –

Respuesta

6

Si son 3 menús desplegables separados, tendrá que validarlos como tres valores separados.

Es decir,

  • Validar que la columna del año es numérico y entre lo años son válidos en su aplicación
  • Validar que la columna del mes es numérico
  • Validar que la columna del día es numérico
  • Validar que todos ellos son valores válidos utilizando checkdate()

o, usted podría simplemente los lanzas al l entero, combinarlos juntos en una fecha, y ver si la fecha resultante es válida. Es decir,

$time = mktime(0, 0, 0, (int)$_POST['month'], (int)$_POST['day'], (int)$_POST['year']); 

// in this example, valid values are between jan 1 2000 (server time) and now 
// modify as required 
if ($time < mktime(0, 0, 0, 1, 1, 2000) || $time > time()) 
    return 'Invalid!'; 

$mysqltime = date('Y-m-d', $time); 

// now insert $mysqltime into database 

La desventaja de este método es que sólo se va a trabajar con fechas dentro de la gama de Unix timestamp es decir, 1.970 a 2.038 o menos.

+0

Probablemente desee comprobar si se trata de un número entero, no si es numérico. is_numeric vale para flotantes y enteros, pero is_int solo comprueba enteros. – gpojd

+0

is_int() no puede funcionar en variables enviadas por el usuario, es decir, variables en $ _POST, porque estas siempre son de tipo cadena. Sin embargo, podría convertirlos en enteros usando (int) $ _ POST ['var'] y luego compararlos libremente con el valor de cadena original (usando ==). – thomasrutter

2

Puede verificar que la fecha sea válida usando checkdate. Si desea asegurarse de que los valores sean numéricos y la longitud correcta, puede hacer algo tan simple como is_int ctype_digit y una combinación strlen antes de construir la fecha.

// untested 
if(!ctype_digit)($month) || strlen($month) != 2) { 
    // handle error 
} 
// repeat for $day and $year 
if (checkdate($month, $day, $year) { 
    // do your work 
} 
+0

Cambié mi respuesta de is_int a ctype_digit según el comentario de thomasrutter de que is_int no manejará correctamente las variables POST. – gpojd

-1

Si tiene tres listas desplegables, los valores que provengan de las listas desplegables siempre deben ser números, ya que controla los valores asociados con el mes (como se muestra a continuación). Esto llevaría a la conclusión de que el resultado combinado es válido.

<option value="01">January</option> 

Si proporciona proporcionar asistencia entradas en los menús desplegables, tales como "Seleccione un mes", entonces puede hacer que el valor 0 y asegurar que los valores procedentes de cada caja de caída es mayor que cero.

Existe la posibilidad de que alguien altere el formulario HTML para proporcionar otros valores. Si esto es una preocupación, entonces puede usar la función PHP ctype_digit() para verificar que cada valor proporcionado sea en realidad un dígito numérico.

Si le preocupa que la fecha sea realmente válida, use la función checkdate().

+0

Es posible realizar publicaciones en una secuencia de comandos sin el uso de formularios. Puedo escribir un bot que haga una publicación en su formulario y publique cualquier valor que ponga en cada campo sin el uso de formularios. –

+0

Eso es cierto y por eso la sugerencia de usar ctype_digit() y checkdate() tiene sentido. Estaba basando mi respuesta en la afirmación de que tenía un formulario. Incluso si usa una secuencia de comandos, no hay muchos casos en esta instancia en los que no use los valores en los formularios. – Paulo

1

Acabo de tener el mismo problema. Escribí una función corta que comprueba si el formato es correcto, y también si la fecha es real:

function valid_mysql_date($str){ 
    $date_parts = explode('-',$str); 
    if (count($date_parts) != 3) return false; 
    if ((strlen($date_parts[0]) != 4) || (!is_numeric($date_parts[0]))) return false; 
    if ((strlen($date_parts[1]) != 2) || (!is_numeric($date_parts[1]))) return false; 
    if ((strlen($date_parts[2]) != 2) || (!is_numeric($date_parts[2]))) return false; 
    if (!checkdate($date_parts[1], $date_parts[2] , $date_parts[0])) return false; 
    return true; 
} 

espero que ayude.

+1

hay checkdate(), amigo –

+0

gracioso, ahora estoy tratando de entender lo que me pasa ... :) –

+0

ok ahora entiendo lo que quise decir, porque hoy me encontré con el mismo problema. checkdate() solicita tres parámetros. así que si tienes una cadena de citas, no te ayuda. mi función recibe una cadena y la formatea y comprueba con checkdate() –

17

Yo he encontrado que esto es la forma correcta y elegante para determinar si la fecha es a la vez de acuerdo al formato y válida:

  • trata fechas como 20111-03-21 como no válido - a diferencia de checkdate()
  • sin posibles advertencias de PHP (si se proporciona algún parámetro, naturalmente) - a diferencia de la mayoría de las soluciones explode()
  • toma un salto año en cuenta las diferencia de las soluciones de expresiones regulares de sólo
  • totalmente compatible con el formato de MySQL DATE (10/03/21 es el mismo que el 2010-03-21)

Aquí está el método que puede utilizar:

/** 
* Tests if a string is a valid mysql date. 
* 
* @param string date to check 
* @return boolean 
*/ 
function validateMysqlDate($date) 
{ 
    return preg_match('#^(?P<year>\d{2}|\d{4})([- /.])(?P<month>\d{1,2})\2(?P<day>\d{1,2})$#', $date, $matches) 
      && checkdate($matches['month'],$matches['day'],$matches['year']); 
} 
+0

Sí, $ str debe cambiarse a $ date ... [función editada] – Ricky

+0

Gracias, de alguna manera, la que uso en producción es correcta, perdón por el error. – raveren

+0

bueno! esto es útil –

4

estoy usando esta función:

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

// check it: 
    $a = validateMysqlDate('2012-12-09 09:04:00'); 
    $b = validateMysqlDate('20122-12-09 09:04:00'); 
    $c = validateMysqlDate('2012-12_09 09:04:00'); 
    $d = validateMysqlDate(''); 
    var_dump($a); 
    var_dump($b); 
    var_dump($c); 
    var_dump($d); 
?> 

$ a es verdadera, las demás son falsas - y tha t es correcto

La función de Raveren (arriba) no cubrirá fechas válidas con marcas de tiempo !!! $ a devuelve falso allí! Y btw: checkdate() devolvería true para $ b aunque no es una fecha de inicio de sesión de mysql válida

+0

Gracias, su función me ayudó :) –

+0

Esto * incorrectamente * invalidará '10.03.21 00: 00: 00' y no validará cadenas de fechas sin tiempo * en absoluto * - que solicitó el OP. – raveren