Из архива Linux16.net: Летнее время в Java

(Опубликовано Mabel aka Yababay, 2009-03-19)

Работаю над GPS-проектом и столкнулся с проблемой, когда трекер передает на сервер время на час большее, чем реальное. Причина выяснилась быстро — китайские производители устройства не учли переход на летнее время. Можно было оставить всё как есть и потерпеть несколько дней: в конце марта переведем часы и искажения исчезнут сами собой. Можно было избавиться от проблемы на скорую руку, т.е. где-нибудь в SQL-процедурах добавить что-то вроде "… — INTERVAL '1 HOUR' ". Но решил таки сделать всё как следует.


Прежде всего прочитал статью в Википедии о летнем времени. Оказывается, тонкости есть. Во-первых, так называемые «малые устройства» как правило не оснащаются автоматическим механизмом перехода на летнее время и обратно, в отличие от персональных компьютеров, сотовых телефонов и т.п. Во-вторых, в Китае, где производятся наши трекеры, от летнего времени отказались вообще. Поэтому полгода сдвиг в передаваемых параметрах времени есть, полгода его нет. В-третьих, к немалому моему удивлению, в стандартных библиотеках Java не удалось найти готовой процедуры выяснения действует в данный момент летнее время или нет. Видимо, это связано с огромным разнобоем в вопросе перехода на него в разных странах. В Канаде, например, в ряде провинций люди бойкотируют летнее время, в США переход на зимнее осуществляется в 2 ночи, в России — в 3, плюс у нас оно накладывается на декретное время, которое действует не во всех регионах. Пришлось, короче говоря, писать механизм определения летнего времени самостоятельно. Если я плохо поискал и такая процедура есть в стандартном API — подскажите, буду признателен. Однако небольшое упражнение на использование класса java.util.Calendar никому не повредит. Вот какой фрагмент кода можно использовать чтобы определять действует летнее время или нет:

import java.util.Calendar;
import java.util.Date;

...

 private static Calendar cldr;
 private static boolean summerTime;

 static{
  cldr = Calendar.getInstance();
  cldr.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
  Calendar c = (Calendar)cldr.clone();
  c.set(c.MONTH,       c.MARCH);
  c.set(c.HOUR_OF_DAY, 2);
  for(int i = 31; i > 0; i--){
   c.set(c.DAY_OF_MONTH, i);
   if(c.get(c.DAY_OF_WEEK) == c.SUNDAY) break;
  }
  Date inMarch = c.getTime();
  c.set(c.MONTH,       c.OCTOBER);
  c.set(c.HOUR_OF_DAY, 3);
  for(int i = 31; i > 0; i--){
   c.set(c.DAY_OF_MONTH, i);
   if(c.get(c.DAY_OF_WEEK) == c.SUNDAY) break;
  }
  Date inOctober = c.getTime();
  Date now = new Date();
  sommerTime =  now.after(inMarch) && now.before(inOctober);
 }    

 public static boolean isSummerTime(){
  return summerTime;
 }


В переводе не обычный язык это означает, что если текущая дата находится между 2:00 последнего воскресенья марта и 3:00 последнего воскресенья октября, то время летнее. Отмечу, что в первых реализациях Java для работы с датами использовался напрямую класс java.util.Date. Но уже давно большинство его методов помечены как deprecated, то есть их использования нужно по максимуму избегать и задействовать гораздо более гибкий Calendar.
  • +1
  • 10 февраля 2010, 15:40
  • yababay

Комментарии (1)

RSS свернуть / развернуть
+
0
Интересно и познавательно! Спасибо, Учтем !
avatar

Markony

  • 10 февраля 2010, 19:01

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.