Получите фактическую экономию летнего времени в миллисекундах

Я делаю аналоговые часы в Java Swing. Для расчета углов стрелки часов мне нужно:

  1. Время UTC в миллисекундах, которое я могу получить с помощью System.currentTimeMillis()
  2. Смещение часового пояса
  3. Экономия часового пояса на летнее время.

Для 2) и 3) я подумал об использовании TimeZone.getDefault().getRawOffset() и TimeZone.getDefault().getDSTSavings().

Но getDSTSavings() всегда возвращает 3600000 независимо от текущей даты в зимнее/летнее время.
Похоже, он только проверяет, находится ли эта зона под управлением DST, и если да, возвращает 3600000, иначе 0.
Является ли это ошибкой? в getDSTSavings()?
Если нет, то единственный способ получить текущую DST поправку в миллисекундах — это использовать экземпляр календаря, например: 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

person zlatanmomic    schedule 08.11.2010    source источник


Ответы (2)


Вот пример использования летнего времени:

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

Будет напечатано 3600000, если в указанную дату в Лондоне действует летнее время. В противном случае он напечатает 0.

person dogbane    schedule 08.11.2010
comment
Да, это то, что я искал. Смещение зависит только от зоны и времени. Теперь мне не нужно создавать новый экземпляр календаря на каждом тике. Вместо этого просто определите текущую зону при запуске часов. конечный часовой пояс timeZone = TimeZone.getDefault(); final long utcTime = System.currentTimeMillis(); окончательный длинный timeOffset = timeZone.getOffset(utcTime); final long t = utcTime + timeOffset; - person zlatanmomic; 09.11.2010

Экземпляр cal1, который вы извлекаете в первой строке, находится в GMT+1 и не меняется независимо от того, какое время/дату вы установили для него. Если вам нужно проверять текущий часовой пояс на каждом такте часов, вам нужно будет получать новый экземпляр календаря на каждом такте.

В качестве примечания, если вы хотите добавить зависимость в свой проект - Joda Time замечательная библиотека даты и времени.

person DaGGeRRz    schedule 08.11.2010