Debido a la modificación del cambio de horario en Chile para este año 2008 que traslada el término de horario de verano desde la noche del 8 de marzo hacia la noche del 29 de marzo, nos hemos topado con la necesidad de corregir nuestros sistemas para que se adapten a este cambio.
En LINUX, la solución más apropiada es la actualización manual de la definición de la zona horaria America/Santiago o (idealmente) la actualización del paquete tzdata (una vez que hayan publicado la actualización correspondiente).
Sin embargo, algunos software como por ejemplo PHP y JAVA mantienen su propia información de zona horaria (zoneinfo) por lo que ingnorarán las reglas que tenga definido el sistema operativo. Esto significa que -aunque yamos parchado nuestro sistema operativo- mantendrán el problema del cambio de hora.
Solución para PHP
PHP desde la versión 5.1 mantiene su propia base de datos de zona horaria por lo que ignorará las reglas de zona horaria definidas en el Sistema Operativo. La solución a este problema es la actualización del módulo timezonedb incluido con PHP.
Gestión de módulos en PHP mediante PECL
PHP está compuesto por un core llamado Zend Engine y un subconjunto de módulos que le agregan funcionalidades como manejo de strings, manejo de fechas, soporte a sesiones, etc. El conjunto de módulos adicionales de PHP se llama PECL.
Es posible agregar módulos PECL adicionales que no vienen incluidos en la distribución original mediante el comando pecl el cual viene en el paquete php-devel.
En las distribuciones RedHat y sus derivados (Fedora Core, CentOS, etc.) la instalación de paquetes se puede realizar con el comando yum, el cual utilizaré como ejemplo en este artículo. En otras distribuciones existen otros gestores de paquetes y los nombres de los paquetes podrían variar.
En caso que no tengamos el paquete php-devel, lo instalamos con el comando:
yum install php-develAhora que contamos con el comando phpize, el procedimiento para instalar cualquier módulo PECL es el siguiente:
pecl instal nombre_paquetePor lo tanto, para instalar el módulo timezonedb se ejecutaría el siguiente comando
pecl install timezonedb
Actualizado: Hace algunos días publiqué un bug en el sitio de PHP y se acaba de liberar la versión de timezonedb que actualiza la zona horaria para America/Santiago, por lo que desde ahora ya no es necesario realizar los pasos que indico en "Instalar módulo timezonedb parchado" sino que simplemente se debe ejecutar el comando indicado a continuación y luego seguir con los pasos indicados más abajo en "Habilitando extensión":
pecl install timezonedb
Instalar módulo timezonedb parchado
El procedimiento a seguir es descargar los fuentes de timezonedb (que están en lenguaje C), modificar la definición de la zona America/Santiago y luego agregar el módulo a PHP. Este procedimiento requiere de conocimientos básicos del lenguaje C.
En primer lugar descargamos los fuentes mediante:
pecl download timezonedbEsto descargará un archivo con la versión más reciente del módulo que en mi caso fue timezonedb-2007.11.tgz. Lo descomprimimos y entramos al directorio recien creado:
tar xfz timezonedb-2007.11.tgzEl archivo timezonedb.h es el que contiene la información de las zonas horarias. He publicado una versión parchada que contiene la información actualizada para America/Santiago en base a la versión timezonedb-2007.11. A contnuación descargamos y descompriminos el archivo.
cd timezonedb-2007.11
wget http://www.joserodriguez.cl/blog/2008/03/timezonedb.h.gzLuego, estamos en condiciones de compilar el módulo ejecutando los siguientes comandos:
gunzip timezonedb.h.gz
phpizeLuego, como usuario root, instalamos el módulo.
./configure
make
make install
Habilitando extensión
Habilitamos la extensión en el archivo php.ini el cual usualmente se encuentra en /etc/php.ini. En algunas distribuciones tales como UBUNTU existen dos archivos php.ini, ambos deben ser actualizados.
echo "extension=timezonedb.so" >> /etc/php.ini
Validando instalación
Para verificar que la actualización funcione correctamente podemos ejecutar el siguiente script:
<?phpCuya salida debería ser la siguiente:
f(1204988400);
f(1205074800);
f(1206802800);
f(1206889200);
function f($time) {
echo date("Y-m-d G:i:s O e I\n", $time);
}
?>
2008-03-08 12:00:00 -0300 America/Santiago 1En caso que ocurra algún error fatal al ejecutar PHP, como por ejemplo segmentation fault, se puede deshabilitar la extensión eliminando la línea recien agregada a php.ini.
2008-03-09 12:00:00 -0300 America/Santiago 1
2008-03-29 12:00:00 -0300 America/Santiago 1
2008-03-30 11:00:00 -0400 America/Santiago 0
Actualizado el 16 de marzo de 2008.