Conversión de zona horaria
Necesito convertir de una zona horaria a otra zona horaria en mi proyecto.
Puedo convertir de mi zona horaria actual a otra, pero no de una zona horaria diferente a otra.
Por ejemplo, estoy en India y puedo convertir de India a EE. UU. usandoDate d=new Date();
y asignándolo a un objeto de calendario y configurando la zona horaria.
Sin embargo, no puedo hacer esto desde una zona horaria diferente a otra. Por ejemplo, estoy en India, pero tengo problemas para convertir las zonas horarias de EE. UU. al Reino Unido.
tl; dr
ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" )) // Current moment in a particular time zone.
.withZoneSameInstant( ZoneId.of( "Asia/Kolkata" )) // Same moment adjusted into another time zone.
Detalles
La clase java.util.Date no tiene zona horaria asignada † , sin embargo, su toString
implementación aplica de manera confusa la zona horaria predeterminada actual de la JVM.
Evite java.util.Date y .Calendar
Esta es una de las muchas razones para evitar las notoriamente problemáticas clases java.util.Date, .Calendar y SimpleDateFormat incluidas con Java. Evítales. En su lugar utilice:
- El paquete java.time integrado en Java 8 e inspirado en Joda-Time.
- Tiempo Joda
java.tiempo
Java 8 y posteriores tienen el paquete java.time incorporado. Este paquete se inspiró en Joda-Time . Si bien comparten algunas similitudes y nombres de clases, son diferentes; cada uno tiene características de las que carece el otro. Una diferencia notable es que java.time evita constructores y en su lugar utiliza métodos de creación de instancias estáticos. Ambos marcos están dirigidos por el mismo hombre, Stephen Colbourne .
Gran parte de la funcionalidad java.time se ha adaptado a Java 6 y 7 en el proyecto ThreeTen-Backport . Adaptado aún más a Android en el proyecto ThreeTenABP .
En el caso de esta Cuestión, funcionan de la misma manera. Especifique una zona horaria y llame a un now
método para obtener el momento actual, luego cree una nueva instancia basada en la antigua instancia inmutable para ajustarla a la zona horaria.
Tenga en cuenta las dos clases de zonas horarias diferentes. Una es una zona horaria con nombre que incluye todas las reglas para el horario de verano y otras anomalías similares más una compensación de UTC, mientras que la otra es solo la compensación.
ZoneId zoneMontréal = ZoneId.of("America/Montreal");
ZonedDateTime nowMontréal = ZonedDateTime.now ( zoneMontréal );
ZoneId zoneTokyo = ZoneId.of("Asia/Tokyo");
ZonedDateTime nowTokyo = nowMontréal.withZoneSameInstant( zoneTokyo );
ZonedDateTime nowUtc = nowMontréal.withZoneSameInstant( ZoneOffset.UTC );
Tiempo Joda
A continuación se muestra un código de ejemplo en Joda-Time 2.3. Busque en StackOveflow muchos más ejemplos y mucha discusión.
DateTimeZone timeZoneLondon = DateTimeZone.forID( "Europe/London" );
DateTimeZone timeZoneKolkata = DateTimeZone.forID( "Asia/Kolkata" );
DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime nowLondon = DateTime.now( timeZoneLondon ); // Assign a time zone rather than rely on implicit default time zone.
DateTime nowKolkata = nowLondon.withZone( timeZoneKolkata );
DateTime nowNewYork = nowLondon.withZone( timeZoneNewYork );
DateTime nowUtc = nowLondon.withZone( DateTimeZone.UTC ); // Built-in constant for UTC.
Tenemos cuatro representaciones de un mismo momento en la línea de tiempo del Universo.
† En realidad, la java.util.Date
clase tiene una zona horaria oculta dentro de su código fuente . Pero la clase ignora esa zona horaria para la mayoría de los fines prácticos. Entonces, para abreviar, a menudo se dice que juDate no tiene zona horaria asignada. ¿Confuso? Sí. Evite el desorden que es juDate y opte por Joda-Time y/o java.time.
Algunos ejemplos
Convertir tiempo entre zonas horarias
Conversión de horas entre zonas horarias
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class TimeZoneExample {
public static void main(String[] args) {
// Create a calendar object and set it time based on the local
// time zone
Calendar localTime = Calendar.getInstance();
localTime.set(Calendar.HOUR, 17);
localTime.set(Calendar.MINUTE, 15);
localTime.set(Calendar.SECOND, 20);
int hour = localTime.get(Calendar.HOUR);
int minute = localTime.get(Calendar.MINUTE);
int second = localTime.get(Calendar.SECOND);
// Print the local time
System.out.printf("Local time : %02d:%02d:%02d\n", hour, minute, second);
// Create a calendar object for representing a Germany time zone. Then we
// wet the time of the calendar with the value of the local time
Calendar germanyTime = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"));
germanyTime.setTimeInMillis(localTime.getTimeInMillis());
hour = germanyTime.get(Calendar.HOUR);
minute = germanyTime.get(Calendar.MINUTE);
second = germanyTime.get(Calendar.SECOND);
// Print the local time in Germany time zone
System.out.printf("Germany time: %02d:%02d:%02d\n", hour, minute, second);
}
}
Date date = new Date();
String formatPattern = ....;
SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);
TimeZone T1;
TimeZone T2;
// set the Calendar of sdf to timezone T1
sdf.setTimeZone(T1);
System.out.println(sdf.format(date));
// set the Calendar of sdf to timezone T2
sdf.setTimeZone(T2);
System.out.println(sdf.format(date));
// Use the 'calOfT2' instance-methods to get specific info
// about the time-of-day for date 'date' in timezone T2.
Calendar calOfT2 = sdf.getCalendar();
La zona horaria "predeterminada" se puede evitar por completo simplemente configurando la zona horaria apropiada para el Calendar
objeto. Sin embargo, personalmente le sugeriría que utilice Joda Time como una API muy superior para operaciones de fecha y hora en Java. Entre otras cosas, la conversión de zona horaria es muy sencilla en Joda.
No está claro cómo se ve su código actual y por qué solo puede convertir a través de la zona horaria predeterminada, pero en Joda Time simplemente especificaría la zona horaria explícitamente al crear (digamos) un DateTime
objeto y luego usaría withZone(DateTimeZone zone)
.
Si pudiera contarnos más sobre cómo obtiene los datos de entrada, podríamos darle un ejemplo más completo.
Puede utilizar el siguiente fragmento de código
String dateString = "14 Jul 2014 00:11:04 CEST";
date = formatter.parse(dateString);
System.out.println(formatter.format(date));
// Set the formatter to use a different timezone - Indochina Time
formatter.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok"));
System.out.println("ICT time : "+formatter.format(date));