Convirtiendo fechas entre zonas horarias (2)

sábado, 12 de diciembre de 2009

En mi anterior post titulado Convirtiendo fechas entre zonas horarias puse un ejemplo de cómo poder convertir una fecha/hora de una zona horaria local a una distinta. Pero trabajando con el mismo proyecto encontré que debía convertir una fecha de la zona horaria UTC a la local, y entonces mi líder técnico me dió una solución sencilla cambiando solo una línea del código de ejemplo del post anterior, justo para hacer lo que necesitaba en ese momento:

En la tarea que estaba realizando leía un archivo de texto con el dato "fecha" como una serie de números: "20090921"+"1230", que representa el 21 de Septiembre de 2009 a las 12:30; por lo que tuve que usar el formato de fecha "yyyyMMddkkmm". Esta fecha que recibía del archivo representaba una fecha/hora en el horario GMT. Y esta hora la debía pasar a mi zona horaria local que es CST o UTC-6 (Tiempo del centro).

public void cambiarZonaHoraria( String fecha, String patron, String tz ) {
SimpleDateFormat format = new SimpleDateFormat( patron );
format.setTimeZone(TimeZone.getTimeZone( tz ));
try {
System.out.println( format.parse( fecha ) );
} catch (ParseException pe) {
pe.printStackTrace();
}
}


Lo que hace es muy sencillo:
  • Primero crea una nueva instancia de SimpleDateFormat con el parámetro "patron" que le dice a la instancia que el texto que se le va a enviar está en ese formato, en mi caso "yyyyMMddkkmm".
  • Luego, lo más importante de lo que intentamos hacer, le asignaremos a nuestro objeto format el TimeZone en el que está la hora que queremos convertir, en mi caso era GMT.
  • Posteriormente, simplemente usamos el método parse(String) para convertir nuestro texto a un Date en la zona horaria local, en mi caso CST; por lo que el resultado final de este ejemplo es que el texto "200909211230" con el formato "yyyyMMddkkmm"lo cual representa "2oo9/09/21 12:30" en GMT pasa a ser "2009/09/21 6:30" en CST ya que son 6 horas menos a la referencia del Tiempo Universal Coordinado o UTC.
Solo debemos recordar cachar las excepciones o hacer un throw de ellas.

Convirtiendo fechas entre zonas horarias

domingo, 6 de diciembre de 2009

En cierto proyecto en el que estoy involucrado tuve que convertir algunas fechas en el huso horario UTC (GMT) a la zona horaria CST (Tiempo del centro) que es el que usa la mayoría de los estados en México. Como el proyecto está enteramente basado en tecnología Java, me di a la tarea de encontrar formas de hacer esto con librerías para Java.

Encontré que hay algunas librerías, como las de Quartz, implementan alguna clase para la conversión de zonas horarias. Pero en mi caso, necesitaba no depender tanto de librerías de terceros o fuera del API de Java.

Encontré que con las clases TimeZone y DateFormat puedo hacer la conversión usando las siguientes sentencias.


public void cambiarZonaHoraria(Date fecha, String to) {
DateFormat dateFormat = new SimpleDateFormat();
TimeZone tz = TimeZone.getTimeZone(to);
dateFormat .setTimeZone(tz);
System.out.println(dateFormat.format(fecha));
}


Lo que se hace básicamente es

  • crear una instancia de SimpleDateFormat con el formato de fecha local
  • crear una instancia del TimeZone con el nombre corto de la zona horaria que se especifique por el parámetro "to"
  • se asigna la nueva zona horaria al objeto dateFormat
  • haciendo uso del método format() del objeto dateFormat se hace la conversión de nuestra fecha a una cadena que representa la nueva fecha en la zona horaria que hemos creado, y esta fecha se imprime en pantalla.
De la misma forma se pueden hacer conversiones entre distintos husos y zonas horarias.
Ahora, cabe señalar que para crear un TimeZone se usa el nombre corto de la zona horaria. Aquí dejo un listado de zonas horarias con sus nombres e IDs que he obtenido ejecutando este pequeño programa que encontré en Java Developers Almanac:

import java.util.Date;
import java.util.TimeZone;

public class ListadoZonasHorarias {

public static void main( String[] args ) {
Date fecha = new Date();
// Obtiene el ID de todas las zonas horarias
String[] zoneIds = TimeZone.getAvailableIDs();

System.out.println(" ID | Nombre corto | Nombre largo |Diferencia horaria \n");
for (int i=0; i<zoneIds.length; i++) {
// Ontiene el TimeZone dependiendo del ID e imprime el ID
TimeZone tz = TimeZone.getTimeZone(zoneIds[i]);
System.out.print(tz.getID() + "\t|");

// Obtiene e imprime el nombre corto y largo de la zona horaria
String shortName = tz.getDisplayName(tz.inDaylightTime(fecha), TimeZone.SHORT);
String longName = tz.getDisplayName(tz.inDaylightTime(fecha), TimeZone.LONG);
System.out.print(shortName + "\t\t|");
System.out.print(longName + "\t|");

// Obtiene e imprime la cantidad de horas de diferencia al huso GMT
int ro = tz.getRawOffset();
int horas = ro / (60*60*1000);
int minutos = Math.abs(ro / (60*1000)) % 60;
System.out.print(horas + ":" + minutos);
System.out.println();
}

}
}

Espero que les pueda servir como a mí. Saludos.