2012-11-02 29 views
18

Ich versuche eine einfache Konvertierung von einer Zeitzone in eine andere mit Java Datum und Kalender zu erreichen. Ich versuche, den folgenden CodeDatum in andere Zeitzone umwandeln

Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("Europe/London")); 
    Date date = instance.getTime(); 
    System.out.println(date); 

    GregorianCalendar instance2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Athens")); 
    instance2.setTime(instance.getTime()); 
    System.out.println(instance2.getTime()); 

aber, dass nach wie vor gibt das gleiche Datum, anstatt 1 Stunde ... Das ganze Problem scheint trivial zu laufen, aber ich kann keine einfache Antwort auf diese findet. Vielen Dank im Voraus für Ihre Hilfe.

+4

Möchten Sie [Joda Zeit] (http://stackoverflow.com/a/375803/1037210) verwenden? Es ist meine Vorliebe. – Lion

+0

Überprüfen Sie [diese Antwort] (http://stackoverflow.com/questions/230126/how-to-handle-calendar-timezones-using-java). Es könnte nützlich sein. – Gamb

+0

Ich fand eine andere Sache im Internet, die wahrscheinlich die sauberste Lösung ist, ein Datumsformat zu verwenden, um die Datumszeichenfolge zu analysieren und das Datum in der entsprechenden Zeitzone zurückzugeben. – Bober02

Antwort

31

Wenn Sie das Datum mit System.out.println(date); or System.out.println(instance2.getTime()); drucken, die Date von instance2.getTime() zurückgekehrt ist TimeZone independent und immer druckt das Datum in der lokalen Zeitzone.

Stattdessen können Sie DateFormat/SimpleDateFormat verwenden:

DateFormat formatter= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss Z"); 
    formatter.setTimeZone(TimeZone.getTimeZone("Europe/London")); 
    System.out.println(formatter.format(date)); 

    formatter.setTimeZone(TimeZone.getTimeZone("Europe/Athens")); 
    System.out.println(formatter.format(instance2.getTime())) 
+0

Sind Sie sicher, dass es sich um die lokale Zeitzone handelt und nicht um EPOCH-Sekunden (zeitzonenunabhängig)? http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getTime() – akaIDIOT

+0

@akaIDIOT die interne Darstellung ist seit der Epoche, wenn das Datum gedruckt wird, wird die lokale Zeitzone verwendet , ein Feature/Bug von 'java.util.Date'. – dan

+0

@ Bober02: Hast du etwas besseres gefunden? Wenn ja, bitte teilen. –

2

Sie können den folgenden Code verwenden Snippet

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)); 
8

Die akzeptierte Antwort richtig ist. Die Klasse java.util.Date hat keine zugewiesene Zeitzone , aber die Implementierung toString wendet die aktuelle Standardzeitzone der JVM verwirrend an.

Vermeiden java.util.Date & .Calendar

Dies ist einer von vielen Gründen, die notorisch mühsam java.util.Date, .Calendar und Simple Klassen mit Java gebündelt zu vermeiden. Vermeide sie. Stattdessen verwenden entweder:

Joda-Time

Einige Beispiel-Code in Joda-Time 2.3 folgt. Durchsuchen Sie StackOveflow nach vielen weiteren Beispielen und vielen Diskussionen.

DateTimeZone timeZoneLondon = DateTimeZone.forID("Europe/London"); 
DateTimeZone timeZoneAthens = DateTimeZone.forID("Europe/Athens"); 

DateTime nowLondon = DateTime.now(timeZoneLondon); 
DateTime nowAthens = nowLondon.withZone(timeZoneAthens); 
DateTime nowUtc = nowLondon.withZone(DateTimeZone.UTC); 

java.time

Java 8 und hat später eine neue java.time package eingebaut. Dieses Paket wurde von Joda-Time inspiriert. Während sie einige Ähnlichkeiten und Klassennamen teilen, sind sie unterschiedlich; jeder hat Merkmale, die anderen fehlen. Ein bemerkenswerter Unterschied besteht darin, dass java.time Konstruktoren vermeidet und stattdessen statische Instanziierungsmethoden verwendet.

Im Falle dieser Frage funktionieren sie in der gleichen Weise. Geben Sie eine Zeitzone an und rufen Sie eine Methode now auf, um den aktuellen Zeitpunkt abzurufen, und erstellen Sie dann eine neue Instanz basierend auf der alten unveränderlichen Instanz, um die Zeitzone anzupassen.

Beachten Sie die zwei verschiedenen Zeitzonen-Klassen. Eine ist eine benannte Zeitzone, die alle Regeln für die Sommerzeit und andere solche Anomalien plus einen Offset von UTC enthält, während die andere nur der Offset ist.

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); 

Tatsächlich ist die java.util.Date Klasse tut eine Zonenzeit innerhalb its source code begraben. Aber die Klasse ignoriert diese Zeitzone für die meisten praktischen Zwecke. Kurz gesagt, es wird oft gesagt, dass j.u.Date keine Zeitzone zugewiesen hat. Verwirrend? Ja. Vermeiden Sie das Durcheinander, das j.u.Date ist und gehen Sie mit Joda-Time und/oder java.time.