2011-08-12 18 views
9

Quiero convertir ms-since-1970-timestamp en una fecha con zona horaria (Alemania).Strange Java Timezone Date Conversion Problema

Éstos son dos variantes de código que funcionó - al menos, recuerdo de usarlo y funcionó:

import java.text.SimpleDateFormat; 
import java.util.Calendar; 
import java.util.Date; 
import java.util.GregorianCalendar; 
import java.util.Locale; 
import java.util.TimeZone; 

public class TestDate { 

    public static void main(String[] args) { 
     Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("Germany"), Locale.GERMANY); 

     Date d = new Date(); 
     cal.setTime(d); 

     System.out.println(String.format("%02d.%02d.%04d %02d:%02d:%02d", 
       cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.MONTH)+1, cal.get(Calendar.YEAR), 
       cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND))); 

     SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss.S"); 
     df.setTimeZone(TimeZone.getTimeZone("Germany")); 
     System.out.println(df.format(d)); 
    } 

} 

Es realmente extraño, porque no podía encontrar la razón de una diferencia de tiempo de 2 horas .

Debe ser: 16:05:20 El código se imprime: 14:05:20 en ambas variantes.

¿Podría alguien ayudarme y decirme qué salió mal aquí?

+1

+1 pregunta – andyb

Respuesta

15

Este es el problema:

TimeZone.getTimeZone("Germany") 

No hay tal vez identificador de la zona, por lo que Java en su infinita sabiduría decide que usted acaba de regresar UTC sin que le dice que está mal nada. Tal vez puedas probar:

TimeZone.getTimeZone("Europe/Berlin") 

Wikipedia tiene un list of IANA time zone IDs, pero es un poco fuera de fecha (en el momento de la escritura); el IANA data es el más actualizado, pero no es tan fácil de navegar ...

-2

El objeto Date no tiene zona horaria.

Date d = new Date(); // here you have you current time - at that moment it was 16:05:20 

Este es el momento en su máquina y tiene GMT + 2. Cuando se utiliza SimpleDateFormat y configurar la zona horaria a continuación se esté viendo la hora UTC.

+0

muy bien escrito como usted dice, la fecha no tiene una zona horaria - es siempre * * el valor GMT, por lo que en ese momento representaba 14:05 GMT. El uso de SimpleDateFormat y la configuración de la zona horaria muestra la hora * local * de acuerdo con la zona horaria indicada, pero desafortunadamente la zona horaria de "Alemania" no existe en realidad, por lo que se estableció como UTC por defecto. El uso de una zona horaria * working * habría mostrado la hora local correcta. –

1

Creo que el problema es la zona horaria predeterminada en la plataforma en la que se está ejecutando.

java.util.Date() tiene un huso horario. Mantiene información de zona horaria "heredada", que, al parecer, se adquiere desde la configuración regional predeterminada del sistema.

este código.

TimeZone tz = TimeZone.getTimeZone("GMT-03:00"); 
Calendar cal = Calendar.getInstance(tz); 
cal.set(1953, 2, 22, 4, 20, 13); 
Date dateTime = cal.getTime(); 
System.out.println(dateTime.toString()); 

produce esto en mi sistema, que es utiliza la configuración regional PST: Sábado 21 23:20:13 PST 1953

No creo que hay una manera de utilizar el java.util.Date object, o los objetos DateFormat que lo usan, para manejar con precisión la información de tiempo de una zona horaria "extranjera".

+0

Las menciones de configuración regional son incorrectas. Locale no tiene nada que ver con la zona horaria. La configuración regional afecta el idioma, como los nombres de días y meses, y los formatos predeterminados para generar representaciones textuales del valor de la fecha y hora. Por ejemplo, podría tener un huso horario en India utilizado con una localidad de Québec ('Locale.CANADA_FRENCH'). –

0

El Answer by Jon Skeet es correcto, ha utilizado un nombre de zona horaria incorrecta.

java.time

Aquí es una solución utilizando los modernos java.time clases que suplantan las clases de fecha y hora de legado viejos que han demostrado ser tan problemático y confuso.

Instant instant = Instant.ofEpochMilli(milliseconds_since_1970); // Or Instant.now() for current moment. 
ZoneId z = ZoneId.of("Europe/Berlin"); 
ZonedDateTime zdt = instant.atZone(z); 

Genera una cadena localizada para representar ese valor de fecha y hora.

Locale l = Locale.GERMANY; // Or Locale.CANADA_FRENCH, etc. 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withLocale(l); 
String output = zdt.format(f);