2010-11-08 17 views
8

Robię analogowy zegar w Java Swing. Aby obliczyć kąty wskaźnika zegara muszę: czasUzyskaj rzeczywiste oszczędności czasu letniego w milisekundach

  1. UTC w milisekundach, które mogę dostać z System.currentTimeMillis()
  2. strefy czasowej
  3. oszczędności TimeZone DST.

Dla 2) i 3) Myślałem o użyciu TimeZone.getDefault().getRawOffset() i TimeZone.getDefault().getDSTSavings().

Jednak zawsze zwraca 3600000, niezależnie od aktualnej daty w okresie zimowym/letnim.
Wygląda na to, że sprawdza tylko, czy ta strefa jest zarządzana pod DST, a jeśli tak, zwraca 3600000 w innym przypadku 0.
Czy jest to błąd w getDSTSavings()?
Jeśli nie, to jedyny sposób, aby uzyskać bieżącą korektę DST w milisekundach, to użycie instancji Kalendarza, takiej jak: Calendar.getInstance.get(Calendar.DST_OFFSET)?

Calendar cal1 = Calendar.getInstance(TimeZone.getDefault());  //currentZone: CET/CEST +1/+2, GMT+1:00 
System.out.println("System time, " + System.currentTimeMillis()); //UTC current milis 
System.out.println("Calendar time, " + cal1.getTime().getTime()); //UTC current milis 
System.out.println("Calendar milis, " + cal1.getTimeInMillis());  //UTC current milis 
System.out.println("Calendar Zone Offset: " + cal1.get(Calendar.ZONE_OFFSET)); 
System.out.println("Calendar DST Offset: " + cal1.get(Calendar.DST_OFFSET)); 
System.out.println("Calendar Zone Offset: " + cal1.getTimeZone().getRawOffset()); 
System.out.println("Calendar DST Offset: " + cal1.getTimeZone().getDSTSavings()); 
System.out.println(""); 

// Winter time, CET 
cal1.set(2010, 11, 15, 14, 15, 5); 
System.out.println("Calendar milis, " + cal1.getTimeInMillis()); //UTC 
System.out.println("Calendar Zone Offset: " + cal1.get(Calendar.ZONE_OFFSET)); // 3600000 correct 
System.out.println("Calendar DST Offset: " + cal1.get(Calendar.DST_OFFSET)); // 0 correct 
System.out.println("Calendar Zone Offset: " + cal1.getTimeZone().getRawOffset()); // 3600000 correct 
System.out.println("Calendar DST Offset: " + cal1.getTimeZone().getDSTSavings()); // 3600000 wrong !!! 
System.out.println(""); 

// Summer time - CEST 
cal1.set(2010, 8, 15, 14, 15, 5); 
System.out.println("Calendar milis, " + cal1.getTimeInMillis()); //UTC 
System.out.println("Calendar Zone Offset: " + cal1.get(Calendar.ZONE_OFFSET)); // 3600000 correct 
System.out.println("Calendar DST Offset: " + cal1.get(Calendar.DST_OFFSET)); // 3600000 correct 
System.out.println("Calendar Zone Offset: " + cal1.getTimeZone().getRawOffset()); // 3600000 correct 
System.out.println("Calendar DST Offset: " + cal1.getTimeZone().getDSTSavings()); // 3600000 correct 

Odpowiedz

12

Oto przykład, w jaki sposób jest wykorzystywany DST:

TimeZone london = TimeZone.getTimeZone("Europe/London"); 
System.out.println(london.getOffset(date.getTime())); 

To będzie drukować 3600000 jeżeli czas letni obowiązuje w Londynie w określonym terminie. W przeciwnym razie wydrukuje 0.

+3

Tak, tego właśnie szukałem. Przesunięcie zależy od strefy i czasu. Teraz nie muszę tworzyć nowej instancji kalendarza przy każdym tiku. Zamiast tego po prostu wykrywaj bieżącą strefę podczas uruchamiania zegara. final TimeZone timeZone = TimeZone.getDefault(); final long utcTime = System.currentTimeMillis(); final long timeOffset = timeZone.getOffset (utcTime); końcowa długa t = utcTime + timeOffset; – zlatanmomic

2

Instancja cal1 pobrana w pierwszym wierszu jest w GMT + 1 i nie zmienia się bez względu na ustawiony czas/datę. Jeśli chcesz sprawdzić aktualną strefę czasową przy każdym tiku zegara, musisz pobrać nową instancję kalendarza przy każdym tiku.

Na marginesie, jeśli chcesz dodać zależność do projektu - Joda Time to wspaniała biblioteka Data i godzina.

Powiązane problemy