2012-11-02 10 views
18

Próbuję uzyskać prostą konwersję z jednej strefy czasowej do drugiej przy użyciu daty Java i kalendarza. Próbuję uruchomić następujący kodKonwersja daty na inną strefę czasową

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

ale wciąż wraca tego samego dnia, zamiast +1 godzinę ... Cały problem wydaje się błahy, ale nie mogę znaleźć żadnej prostej odpowiedzi na to. Z góry dziękuje za twoją pomoc.

+4

Czy chcesz użyć [Joda time] (http://stackoverflow.com/a/375803/1037210)? To moje preferencje. – Lion

+0

Sprawdź [tę odpowiedź] (http://stackoverflow.com/questions/230126/how-to-handle-calendar-timezones-using-java). Może się przydać. – Gamb

+0

Znalazłem inną rzecz w Internecie, która jest prawdopodobnie najczystszym rozwiązaniem, do użycia formatu daty w celu przeanalizowania ciągu daty i zwrócenia daty w odpowiedniej strefie czasowej – Bober02

Odpowiedz

31

Podczas drukowania datę używając System.out.println(date); or System.out.println(instance2.getTime()); The Date zwrócony przez instance2.getTime() jest TimeZone independent i zawsze drukuje datę w lokalnej strefy czasowej.

Zamiast tego możesz użyć DateFormat/SimpleDateFormat:

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

Czy jesteś pewien, że jest to lokalna strefa czasowa, a nie czasy EPOCH (niezależne od stref czasowych)? http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getTime() – akaIDIOT

+0

@akaIDIOT reprezentacja wewnętrzna jest od epoki, kiedy drukowana jest data, używana jest strefa czasowa lokalna , funkcja/błąd 'java.util.Date'. – dan

+0

@ Bober02: Czy znalazłeś coś lepszego? Jeśli tak, proszę udostępnij. –

2

Można użyć następującego kodu 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

Zaakceptowanych odpowiedź jest poprawna. Klasa java.util.Date nie ma przypisanej strefy czasowej , ale jest to implementacja toString w sposób mylący stosuje bieżącą domyślną strefę czasową maszyny JVM.

Unikaj java.util.Date & .Calendar

Jest to jeden z wielu powodów, aby uniknąć kłopotliwego java.util.Date się notorycznie, .Calendar i zajęcia SimpleDateFormat wiązane z Java. Unikaj ich. Zamiast używać albo:

Joda-Time

Niektóre przykładowy kod w Joda-Time 2.3 poniżej. Szukaj StackOveflow na wiele innych przykładów i dyskusji.

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, a później ma nową java.time package wbudowane. Ten pakiet został zainspirowany przez Joda-Time. Chociaż mają pewne podobieństwa i nazwy klas, są różne; każdy ma cechy innych braków. Jedną z istotnych różnic jest to, że java.time unika konstruktorów, zamiast tego używa statycznych metod tworzenia instancji.

W przypadku tego pytania działają one w taki sam sposób. Określ strefę czasową i wywołaj metodę now, aby uzyskać bieżący moment, a następnie utwórz nową instancję na podstawie starej niezmiennej instancji, aby dostosować do strefy czasowej.

Zwróć uwagę na dwie różne klasy stref czasowych. Jednym z nich jest nazwana strefa czasowa zawierająca wszystkie reguły dotyczące czasu letniego i inne takie anomalie plus przesunięcie względem UTC, podczas gdy druga jest tylko przesunięciem.

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

Właściwie klasa java.util.Date robi posiada strefę czasową pochowany wewnątrz its source code. Ale klasa ignoruje tę strefę czasową w większości praktycznych celów. Tak więc, jako skrót, często mówi się, że j.u.Date nie ma przypisanej strefy czasowej. Mylące? Tak. Unikaj bałaganu j.u.Date i korzystaj z Joda-Time i/lub java.time.

Powiązane problemy