miércoles, 8 de octubre de 2008

Ajustar el timezone de Java en Linux


Si en alguna de tus aplicaciones te ha ocurrido que la api de Java (Date o GregorianCalendar) no te da la hora correctamente, aún siendo correcta la del sistema operativo, probablemente se deba a que Java no está interpretando la zona horaria correctamente.

Me sucedió en mi Debian, y lo primero que se me ocurrió fue ajustar el timezone del sistema operativo con el comando tzconfig. Efectivamente, la zona horaria no estaba configurada correctamente, pero aún corrigiendo esto la hora de Java seguía sin ser la correcta.

En concreto mi zona horaria era GTM+2, correspondiente a España en verano, mientras que la JVM me daba GTM+1. En ese momento lo consideré una chorrada. Además el cambio horario estaba cerca y el problema desaparecería al pasar al horario de invierno (GTM+1) :-p. Ha sido hoy cuando la chorrada ha pasado a ser un problema y por ello no he tenido más remedio que buscar la solución.

La solución es bien sencilla

Probablemente ya la sepas, pero soy de los que piensa que más vale encontrar algo útil un millón de veces a no encontrarlo nunca.

Hay tres soluciones posibles:
  1. Ajustar la variable de entorno TZ.

    bash$ export TZ="Europe/Madrid"

  2. Incluir el parámetro -Duser.timezone en la ejecución del comando java.

    bash$ java -Duser.timezone=Europe/Madrid ...."

  3. Ajustar el fichero /etc/localtime para que apunte a la zona horaria correcta. Todas las zonas horarias disponibles se encuentran en /usr/share/zoneinfo.

    bash$ ln -s /usr/share/zoneinfo/Europe/Madrid /etc/localtime


Puedes tomar la solución que veas más conveniente, pero si no eres el administrador de la máquina, probablemente la tercera solución te sea imposible.

Espero que te sea útil.

5 comentarios:

Anónimo dijo...

Muchas gracias.
Tenía el mismo problema.
Java 1.5 y Debian Etch.
Al final lo he puesto como
-Duser.timezone=Europe/Madrid
Y funciona.

Me queda la duda de porqué la JVM no lee correctamente el /etc/timezone estando el /Europe/Madrid correctamente definido. ¿?¿?¿?¿?
Si me entero de algo lo posteo aquí mismo.

Gracias.

Anónimo dijo...
Este comentario ha sido eliminado por un administrador del blog.
kapricho del sur dijo...

En la tercera solución que das "ln -s /usr/share/zoneinfo/Europe/Madrid /etc/localtime" , si el fichero "/etc/localtime" existe nos dará el siguiente mensaje de error:

ln: creando el enlace simbólico «/etc/localtime»: El fichero ya existe

Para forzar al comando a sobreescribir el fichero existente utilizamos la opción "-f", el comando quedaría así:

"ln -sf /usr/share/zoneinfo/Europe/Madrid /etc/localtime" (sin las comillas)

Un saludo

kapricho del sur dijo...

Bueno, se me olvidaba decirte que me ha sido muy útil tu artículo.

Sigue así.

Xela dijo...

Muchas gracias por tu aportación, kapricho del sur. ;-)