Методы GregorianCalendar в календаре, устанавливающие дату на предыдущий день

#java #calendar #gregorian-calendar

#java #Календарь #григорианский календарь

Вопрос:

У меня странная проблема с абстрактным классом Calendar, использующим метод GregorianCalendar.

По какой-то причине использование «calendar.set» возвращает дату предыдущего дня. Смотрите код ниже, например, с комментариями о том, где это работает нормально, а где что-то идет не так.

 private Date checkDate(Date d, int hour, int minute, int sec, int milliSec)
{
    // Test values for arguments
    d = "Wed Apr 06 00:00:00 BST 2011";
    hour = minute = sec = milliSec = 0;

    Calendar calendar = new GregorianCalendar(sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]);
    calendar.setTime(d);

    // *** OK *** calendar.getTime() will display correctly here (Wed Apr 06 00:00:00 BST 2011)

    calendar.set(Calendar.HOUR_OF_DAY, hour);
    calendar.set(Calendar.MINUTE, minute);
    calendar.set(Calendar.SECOND, sec);
    calendar.set(Calendar.MILLISECOND, milliSec);

    // *** NOT OK *** calendar.getTime() will display inncorrectly here (Tue Apr 05 01:00:00 BST 2011)


return calendar.getTime();  
  

}
Есть идеи?

Спасибо

Комментарии:

1. что произойдет, если вы измените значение для перехода на летнее время?

Ответ №1:

 Calendar calendar = new GregorianCalendar(sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]);
calendar.setTime(d);
  

Хорошо, итак, у вас есть календарь с часовым поясом, установленным на UTC, и установите для него время на

Wed Apr 06 00:00:00 BST 2011 .

Внутренне это сопоставляется с

2011-04-05 23:00:00 UTC (дата и время приняты, часовой пояс сохранен).

Установка для полей «час», «минута», «секунда» и «миллисекунда» календаря значения 0 изменит его на

2011-04-05 00:00:00 UTC .

Если вы теперь преобразуете календарь в java.util.Date объект и распечатаете его с учетом вашего местного часового пояса (BST), результатом будет:

2011-04-05 01:00:00 BST .

Ответ №2:

Календарь немного странный, как вы можете прочитать в его javadoc; суть в том, что вам нужно вызывать calendare.get() после каждого вызова calendar.set(…), иначе модификация может быть непоследовательной.