Почему Calendar.after всегда возвращает true? - PullRequest
0 голосов
/ 30 сентября 2019

Привет, может кто-нибудь объяснить, почему такое неправильное поведение из Calendar .after метод

Calendar cal = Calendar.getInstance();
Calendar cal1 = Calendar.getInstance();

cal.set(Calendar.HOUR, 14);
cal1.set(Calendar.HOUR, 13);

System.out.println(cal.after(cal1)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime());      

cal.set(Calendar.DATE, Calendar.getInstance().get(Calendar.DATE));
System.out.println(cal.after(cal1)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime());

Вывод:

true Cal Tue Oct 01 02:55:16 IST 2019 cal1 Tue Oct 01 01:55:16 IST 2019
true Cal Wed Oct 30 02:55:16 IST 2019 cal1 Tue Oct 01 01:55:16 IST 2019

, но я не понял, почему cal после cal1, даже если яустановили дату cal1 на текущую дату,

, поэтому, если cal сегодня, я назначил время в 14 часов для перехода на следующую дату, а затем я установил дату в качестве текущей даты в cal, а для cal1 - нет.

Так почему же все еще cal.after(cal1) показывает значение true во втором сисо, в то время как мой cal1 явно на 1 день больше, чем cal?

Ответы [ 5 ]

1 голос
/ 30 сентября 2019

есть предложения по решению такой проблемы? Используйте java.time

Я согласен с вами, что в вашем коде есть некоторые сюрпризы. Возможно, вы предполагали следующее:

    ZoneId zone = ZoneId.of("Asia/Kolkata");
    ZonedDateTime zdt = ZonedDateTime.now(zone);
    ZonedDateTime zdt1 = ZonedDateTime.now(zone);

    zdt = zdt.withHour(14);
    zdt1 = zdt1.withHour(13);

    System.out.println(zdt.isAfter(zdt1) + " zdt " + zdt + " zdt1 " + zdt1);

    zdt = zdt.withDayOfMonth(ZonedDateTime.now(zone).getDayOfMonth());
    System.out.println(zdt.isAfter(zdt1) + " zdt " + zdt + " zdt1 " + zdt1);

Вывод, когда я только что запустил код:

true zdt 2019-09-30T14:44:13.630029+05:30[Asia/Kolkata] zdt1 2019-09-30T13:44:13.630362+05:30[Asia/Kolkata]
true zdt 2019-09-30T14:44:13.630029+05:30[Asia/Kolkata] zdt1 2019-09-30T13:44:13.630362+05:30[Asia/Kolkata]

Я получаю true оба раза так же, как вы получилииз вашего кода, что не должно удивлять. Как уже говорили другие, 02: 55h - после 01: 55h, а 30 октября - после 01 октября. Также, ссылаясь на мой результат, 14:44 - после 13:44. В обеих строках эти два раза сравниваются.

Я использую java.time, современный Java-интерфейс даты и времени.

Что пошло не так в вашем коде?

сюрпризы в вашем коде проистекают из того, что класс Calendar плохо спроектирован и часто ведет себя не так, как мы ожидаем.

  1. Почему, когда вы устанавливаете час на 14, вы получаете Tue Oct 01 02:55:16 IST 2019? Дата изменилась на следующий месяц, и час дня равен 2, а не 14.
  2. Почему, когда вы устанавливаете дату на сегодняшнюю дату, 30 сентября, вы получаете 30 октября?

Для 1., Calendar.HOUR относится к часу в AM или PM от 0 до 11. Поэтому, установив его на 14, мы должны были ожидать исключения. A Calendar со стандартными настройками не волнует. Поскольку время уже было в PM, оно экстраполируется, поэтому 14:00 становится 2:00 на следующий день. Поскольку сегодня последний день сентября, вы получаете 1 октября.

Для 2. Calendar.DATE относится не к полной дате, а к дню месяца. Поскольку текущим днем ​​месяца является 30, и у нас уже был 1 октября, мы получаем 30 октября.

Короче говоря: Избегайте класса Calendar. Используйте ZonedDateTime и / или другие классы из java.time, современного Java-API даты и времени. С ними гораздо приятнее работать и преподносить гораздо меньше сюрпризов, чем те, с которыми вы столкнулись.

Ссылка

Учебное пособие по Oracle: Дата и время , объясняющее, как использовать java.time.

0 голосов
/ 30 сентября 2019

Использование

cal.setTime((Calendar.getInstance()).getTime());

вместо

cal.set(Calendar.DATE, Calendar.getInstance().get(Calendar.DATE));

дает желаемый результат.

0 голосов
/ 30 сентября 2019

Документы Java для - Calendar.after ()

public boolean after(Object when) {
    return when instanceof Calendar && compareTo((Calendar)when) > 0;
}
        //By definition :- true if the time of this Calendar is after the time represented by when; false otherwise.

        System.out.println(cal.after(cal1)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime());
        //true Cal Tue Oct 01 02:17:46 IST 2019 cal1 Tue Oct 01 01:17:46 IST 2019

        cal.set(Calendar.HOUR, 13);
        cal1.set(Calendar.HOUR, 14);

        System.out.println(cal.after(cal1)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime());
        //false Cal Tue Oct 01 01:16:55 IST 2019 cal1 Tue Oct 01 02:16:55 IST 2019

        cal.set(Calendar.DATE, Calendar.getInstance().get(Calendar.DATE));
        System.out.println(cal.after(cal1)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime());
        //true Cal Wed Oct 30 13:17:46 IST 2019 cal1 Tue Oct 01 14:17:46 IST 2019
0 голосов
/ 30 сентября 2019
         System.out.println(cal.after(cal1)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime()); 
        //true Cal Tue Oct 01 02:25:19 MMT 2019 cal1 Tue Oct 01 01:25:19 MMT 2019  
    cal.set(Calendar.DATE, Calendar.getInstance().get(Calendar.DATE));
    System.out.println(cal1.after(cal)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime());
   //false Cal Wed Oct 30 02:25:19 MMT 2019 cal1 Tue Oct 01 01:25:19 MMT 2019
0 голосов
/ 30 сентября 2019

Calendar.after

public boolean after(Object when) {
    return when instanceof Calendar && compareTo((Calendar)when) > 0;
}
...