Ir directamente al contenido de esta página

0000-00-00

En estos momentos llevamos unas semanas inmersos en el proceso de instalar una aplicación web que hemos creado para uno de nuestros clientes —http://www.alliancemedical.es/— en el servidor de su intranet y, como suele ocurrir en estos casos, surgen situaciones inesperadas; en el caso que nos ocupa, una particularidad de la función strtotime() de PHP.

La aplicación en cuestión es un sistema de seguimiento de gastos en el que todos los empleados de la empresa están registrados. Al acceder, comprobamos si el usuario tiene indicada una fecha de baja en la empresa que haya vencido, en cuyo caso desactivamos su perfil y no le permitimos el acceso. Simplificada, la lógica es la siguiente:

  1. Comprobamos que hay asignada una fecha de baja,
  2. en cuyo caso comparamos la fecha con la del día de hoy, y
  3. si la fecha de baja es anterior o igual a la fecha de hoy, desactivamos el usuario.

Tratándose de algo tan simple, cuando el sistema no funcionaba en el servidor de producción y sí lo hacía en el de desarrollo, empleamos horas revisando la configuración de ambos para intentar dar con el problema… hasta que descubrimos que no estaba ahí.

El problema era el resultado de la evaluación de strtotime(). También simplificando, teníamos un código como:


$baja = srttotime($fecha_baja);

if(!empty($baja)){    /* Si la fecha de baja no es cero/nulo/vacío/falso... */

  if($baja<=$hoy){    /* Si el valor de $baja es menor o igual que el de $hoy */

      [...]           /* Desactiva el usuario */
  }
}
 

$fecha_baja contenía el valor devuelto por la base de datos, que en el caso de las fechas no asignadas era 0000-00-00. Intuitivamente, parece lógico pensar que srttotime('0000-00-00') devolverá 0, pero no. En realidad es FALSE... sobre un sistema operativo de 32 bits. Para uno de 64 bits como el de nuestro cliente, la función devuelve -62169955200, haciéndola, siempre, anterior a la fecha del día en curso.

No hemos encontrado aún una explicación para esto, pero agradecemos a nyctimus su comentario en php.net que nos iluminó al respecto.

Esta entrada se publicó el 7 de diciembre de 2012, se archivó en , y fue etiquetada como . Autor: Saúl González Fernández. Hay 2 comentarios ›.

Comentarios

  1. ViJiOjO dice:

    Estimados compañeros de digitalicOn y visitantes de la página:

    Soy creador y programador de código PHP y Efectivamente en 64 bits produce una respuesta diferente debido a las diferentes arquitecturas de dicho sistema con 32 bits.

    Esta peculiaridad se debe a la imposibilidad de representar una fecha en formato Unix anterior a 1970, sin embargo en 64 bits ya es compresible por el sistema, la diferencia es que el momento 0 segundos para el formato UNIX es el 1 de enero de 1970 a las 00:00 es decir:

    strtotime(“1970-01-01 00:00:00”) = 0

    por tanto en 64 bits la función ante unos segundos antes de ese instante temporal devolvería:

    32 bits: strtotime(“1969-12-31 23:59:55”) = FALSE
    64 bits: strtotime(“1969-12-31 23:59:55”) = -5

    Por tanto, ante la entrada del tiempo 0 devuelve el tiempo en segundos transcurridos desde el momento 0 temporal, es decir el momento 0 del año cero, esto son 1970 años antes, con sus días extras de años bisiestos, pero en realidad se retrasan unas horas más, puesto que no existió un día 0, ni un mes 0, ni un año 0, la fecha no coincide exactamente sino que sería exactamente: 0000-00-00 00:00:00 coincidiría con las 00:00:00 horas del 29 de noviembre del año 1 a.C.

    Si disponen de tiempo hagan los cálculos, pero rápidamente con la respuesta es en segundos si hacemos:

    62169955200 / 3600 / 24 / 365 = 1971,396…

    Lo que corresponde a algo más de 1971 años y 4 meses… es decir 1970 años y todos los días extras de los casi 500 años bisiestos transcurridos hasta esa fecha más algunos ajustes temporales añadidos, ya que realmente un año dura 365 días y 6 horas.

    Por esto me permito añadir que más que una rareza es una consideración a tener en cuenta puesto que la explicación es exacta y no cabe ninguna matización más allá de la meramente técnica o matemática a la hora de obtener dicho resultado.

    Me despido saludando cordialmente a los compañeros programadores y deseando un Feliz 2013 🙂

  2. Saúl González Fernández dice:

    @ViJiOjO: Muchas gracias por la explicación 🙂

¿Algún comentario?

* Los campos con un asterisco son necesarios

Últimos proyectos

© Digital Icon, S.L., 2007 – 2017