2011-08-12 15 views
9

Chcę przekonwertować ms-since-1970-timestamp na datę ze strefą czasową (Niemcy).Dziwny problem konwersji daty strefy czasowej Java

Oto dwa warianty kodu, który pracował - przynajmniej Pamiętam go używać i to działało:

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

} 

To naprawdę dziwne, ponieważ nie mogłem znaleźć przyczynę czasowych różnicą 2 godziny .

Powinno być: 16:05:20 Kod drukuje: 14:05:20 w obu wariantach.

Czy ktoś mógłby mi pomóc i powiedzieć, co poszło nie tak?

+1

+1 ładnie napisany pytanie – andyb

Odpowiedz

15

To jest problem:

TimeZone.getTimeZone("Germany") 

Nie ma takiej strefy czasowej ID, więc Java w jego nieskończonej mądrości decyduje się właśnie powrót UTC bez informacją, że coś jest nie tak. Spróbuj to zamiast:

TimeZone.getTimeZone("Europe/Berlin") 

Wikipedia ma list of IANA time zone IDs, ale to nieco nieaktualne (w momencie pisania); IANA data jest najbardziej aktualny, ale nie jest tak łatwy do przeglądania ...

-2

Obiekt daty nie ma strefy czasowej.

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

Jest to czas na komputerze i ma UTC + 2. Podczas korzystania SimpleDateFormat i ustawić strefę czasową, to jesteś wyświetlanie czasu UTC.

+0

Jak można powiedzieć, data nie posiada strefę czasową - to * zawsze * wartość UTC, więc w tym momencie jest reprezentowana 14:05 UTC. Użycie SimpleDateFormat i ustawienie strefy czasowej wyświetla czas * lokalny * zgodnie z daną strefą czasową - ale niestety strefa czasowa "Niemcy" w rzeczywistości nie istnieje, więc domyślnie była to UTC. Używanie strefy czasowej * działającej * wskazywałoby prawidłowy czas lokalny. –

1

Uważam, że problem jest domyślną strefą czasową na platformie, na której pracujesz.

java.util.Date() ma strefę czasową. Utrzymuje "odziedziczoną" informację o strefie czasowej, która, jak się wydaje, jest pobierana z domyślnych ustawień regionalnych systemu.

ten kod.

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

daje to w moim systemie, który używa locale PST: Sat Mar 21 23:20:13 PST 1953.

ja nie wierzę, że istnieje sposób, aby użyć java.util.Date object, lub obiekty DateFormat, które go używają, do dokładnego przetwarzania informacji o czasie z "zagranicznej" strefy czasowej.

+0

Wzmianki o locale są niepoprawne. Lokalizacja nie ma nic wspólnego ze strefą czasową. Ustawienia regionalne wpływają na język, na przykład na nazwy dni i miesięcy oraz na domyślne formaty generowania tekstowych reprezentacji wartości daty i godziny. Na przykład, możesz mieć strefę czasową w Indiach używaną z lokalizacją Québec ('Locale.CANADA_FRENCH'). –

0

Poprawny jest kod Answer by Jon Skeet, użyto niepoprawnej nazwy strefy czasowej.

java.time

Oto rozwiązanie przy użyciu nowoczesnych java.time klas, które zastąpić dawne klasy Date-Time starszych, które okazały się być tak kłopotliwe i mylące.

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

Generowanie zlokalizowanego łańcucha w celu reprezentowania tej wartości daty i godziny.

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