Vamos a examinar cómo cambiar el time zone de un date en java de distintos modos.
Como cambiar el timezone de un java.util.Date usando SimpleDateFormat
Debemos tener claro que la clase Date en Java no tiene time zone.
java.util.Date representa la cantidad de segundos transcurridos desde la medianoche 1 de enero de 1970 a las cero horas (hora UTC).
Esto significa que siempre el java.util.Date nos devolverá la hora para el time zone que este por default definida para el sistema.
Lo que necesitas hacer para cambiar el time zone a un Date es:
- Crear un DateFormat con el time zone para la zona que queremos
- Aplicar el DateFormat al Date obteniendo un string con modificado
- Volver a crear un object Date a partir de ese string
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class TimeZoneChangeDateExample {
private static final String DATE_FORMAT = "dd-MM-yyyy hh:mm:ss a";
public static void main(String[] args) throws ParseException {
// the date
Calendar cal = Calendar.getInstance();
cal.set(2017, 06, 29, 8, 30);
Date date = cal.getTime();
// format with tz
TimeZone timeZone = TimeZone.getTimeZone("Europe/Amsterdam");
SimpleDateFormat formatterWithTimeZone = new SimpleDateFormat(DATE_FORMAT);
formatterWithTimeZone.setTimeZone(timeZone);
// change tz using formatter
String sDate = formatterWithTimeZone.format(date);
// string to object date
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
Date dateWithTimeZone = formatter.parse(sDate); // string to Date Object
System.out.println("The actual date is: " + formatter.format(date));
System.out.println("The date in " + timeZone.getID() + " is: " + sDate);
System.out.println("Object date: " + formatter.format(dateWithTimeZone));
}
}
La salida de este ejemplo:
The actual date is: 29-07-2017 08:30:54 AM
The date in Europe/Amsterdam is: 29-07-2017 01:30:54 PM
Object date: 29-07-2017 01:30:54 PM
Como cambiar el timezone de un Date usando Calendar
Para cambiar el time zone usando calendar debes:
- Crear un calendar
- Setear el time zone al calendar
- Obtener los valores a través de los gets especificos.
Nota: si intentas obtener el Date directamente, calendar.getTime(), obtendrás la fecha siempre pasada al tiempo local porque lo que devuelve es un java.util.Date y como dijimos antes este no tiene el time zone.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
public class TimeZoneChangeCalendarExample {
private static final String DATE_FORMAT = "dd-MM-yyyy hh:mm:ss a";
public static void main(String[] args) throws ParseException {
// calendar with tx
TimeZone timeZone = TimeZone.getTimeZone("Europe/Amsterdam");
Calendar calendar = Calendar.getInstance();
calendar.set(2017, 06, 29, 8, 30);
calendar.setTimeZone(timeZone);
// get calendar using fields
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
System.out.println("The actual date is: " + formatter.format(calendar.getTime()));
System.out.print("The date in " + timeZone.getID() + " is: ");
System.out.print(" Day:" + dayOfMonth);
System.out.print(" Month:" + (month + 1)); // base zero
System.out.print(" Year:" + year);
System.out.print(" Hour:" + hourOfDay);
System.out.print(" Min:" + minute);
System.out.print(" Sec:" + second);
System.out.println();
// calendar getTime with DateFormat
SimpleDateFormat formatterWithTimeZone = new SimpleDateFormat(DATE_FORMAT);
formatterWithTimeZone.setTimeZone(timeZone);
System.out.println("Calendar.getTime() - Date in Local TZ:" + formatterWithTimeZone.format(calendar.getTime()));
}
}
La salida de este ejemplo:
The actual date is: 29-07-2017 03:30:22 AM
The date in Europe/Amsterdam is: Day:29 Month:7 Year:2017 Hour:8 Min:30 Sec:22
Calendar.getTime() - Date in Local TZ:29-07-2017 08:30:22 AM
Como cambiar el timezone de un Date usando Java 8 en adelante
Para cambiar el time zone de una fecha en Java 8+:
- Crear un LocalDateTime
- Setear el time zone original al LocalDateTime
- Cambiar el time zone de la fecha original
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class TimeZoneChangeZonedDateTime {
public static void main(String[] args) {
LocalDateTime localDateTime = LocalDateTime.of(2018, 06, 29, 8, 30);
// zone from Buenos Aires
ZoneId zoneBuenosAires = ZoneId.of("America/Buenos_Aires");
ZonedDateTime asiaZonedDateTime = localDateTime.atZone(zoneBuenosAires);
// zone from Amsterdan
ZoneId zoneAmsterdan = ZoneId.of("Europe/Amsterdam");
ZonedDateTime nyDateTime = asiaZonedDateTime.withZoneSameInstant(zoneAmsterdan);
// print dateTime with tz
System.out.println("Date : " + asiaZonedDateTime);
System.out.println("Date : " + nyDateTime);
}
}
La salida de este ejemplo:
Date : 2018-06-29T08:30-03:00[America/Buenos_Aires]
Date : 2018-06-29T13:30+02:00[Europe/Amsterdam]
Puedes visitar este post con mayor detalle sobre la nueva api java.time
Conclusión
Este post muestra tres formas de cambiar el time zone para una fecha, partiendo sobre cómo cambiar el time zone para un java.util.Date, luego para un java.util.Calendar y por último en Java8+ haciendo uso de la nueva api java.time.