Научитесь сравнивать два экземпляра ZonedDateTime в одном и том же часовом поясе или в разных часовых поясах в Java 8.
2. Сравнение в один и тот же момент
Как мы знаем, экземпляр ZonedDateTime — это точка на универсальной временной шкале со смещением. Поэтому, чтобы сравнить два таких экземпляра, по логике, оба экземпляра должны сначала находиться в одном часовом поясе, а затем мы должны сравнить значения даты и времени.
Именно это и происходит, когда мы используем следующие методы для сравнения двух экземпляров ZonedDateTime.
- isAfter()
- isBefore()
- isEqual()
Функция zdt1.isAfter(zdt2) сравнивает момент обоих значений даты и времени и аналогична функции zdt1.toInstant().equals(zdt2.toInstant()).
Эти методы не используют сравнение полей, а сравнивают секунды эпохи из обоих экземпляров,
ZonedDateTime zdtNow = ZonedDateTime.now();System.out.println("Time in IST" + zdtNow);ZonedDateTime zdtNowinUTC = zdtNow.withZoneSameInstant(ZoneId.of("UTC"));System.out.println("Time in UTC" + zdtNowinUTC);if(zdtNow.toEpochSecond() == zdtNowinUTC.toEpochSecond()) { //trueSystem.out.println("Epoch Seconds are equal");}System.out.println(zdtNow.isEqual(zdtNowinUTC)); //trueSystem.out.println(zdtNow.isBefore(zdtNowinUTC)); //falseSystem.out.println(zdtNow.isAfter(zdtNowinUTC)); //false
Вывод программы.
2022-02-16T00:17:34.656584400+05:30[Asia/Calcutta]2022-02-15T18:47:34.656584400Z[UTC]Epoch Seconds are equaltruefalsefalse
2. Сравнение по полям
Если у нас есть два экземпляра ZonedDateTime и мы хотим выполнить сравнение полей, то мы можем использовать следующие методы:
- сравнитьС()
- равно()
Оба метода сравнивают экземпляры, включая хронологию. Сравнение основано сначала на моменте, затем на локальной дате-времени, затем на идентификаторе зоны, затем на хронологии. Таким образом, compareTo() сравнивает все 4 информации в обоих экземплярах.
Возвращает отрицательное значение, если меньше, положительное, если больше, и 0, если оба экземпляра даты и времени равны.
ZonedDateTime zdtNow = ZonedDateTime.now();System.out.println("Время в IST" + zdtNow);ZonedDateTime zdtNowinUTC = zdtNow.withZoneSameInstant(ZoneId.of("UTC"));System.out.println("Время в формате UTC" + zdtNowinUTC);System.out.println(zdtNow.compareTo(zdtNowinUTC));System.out.println(zdtNow.equals(zdtNowinUTC));
Вывод программы.
1ЛОЖЬ
3. Сравнение ZonedDateTime во время перехода на летнее время
Мы должны помнить, что ZonedDateTime — это значение даты-времени с идентификатором зоны и информацией о смещении в календарной системе ISO-8601. Обратите внимание, что идентификатор зоны может иметь разные значения смещения в течение года, в основном во время перехода на летнее время(DST), когда значение смещения увеличивается или уменьшается на 1 час.
Для большинства часовых поясов, не использующих летнее время, а также для неперекрывающихся или непересекающихся часовых поясов, на которые распространяется действие летнего времени, методы isEqual(), isBefore() или isAfter() дают последовательные и предсказуемые результаты.
Единственное, что нас беспокоит, — это время наложения(когда часы переводятся вперед) и разрыва(когда часы переводятся назад).
- Для пробелов общая стратегия заключается в перемещении экземпляра в более позднее смещение.
- Для Overlaps предыдущее смещение будет сохранено, если оно доступно. В случае, если предыдущее смещение недоступно или недействительно, предоставлены два дополнительных метода withEarlierOffsetAtOverlap() и withLaterOffsetAtOverlap().
В данном примере даны два экземпляра. Один экземпляр находится в периоде перекрытия, а другой — после периода перекрытия. Обратите внимание на значение смещения, напечатанное в первых двух операторах печати.
Во время перекрытия предыдущее смещение(-05:00) было сохранено. Мы использовали метод withLaterOffsetAtOverlap(), чтобы использовать самое позднее значение смещения, т.е. -06:00.
ZonedDateTime zonedDTDuringOverlap = ZonedDateTime.of(LocalDateTime.of(2021, 11, 07, 1, 05, 53), ZoneId.of("US/Central"));ZonedDateTime zonedDTAfterOverlap = ZonedDateTime.of(LocalDateTime.of(2021, 11, 07, 2, 05, 53), ZoneId.of("US/Central"));System.out.println("During overlap: " + zonedDTDuringOverlap);System.out.println("After overlap(): " + zonedDTAfterOverlap);ZonedDateTime zonedDT = zonedDTDuringOverlap.withLaterOffsetAtOverlap();System.out.println("Using withLaterOffsetAtOverlap(): " + zonedDT);
Вывод программы.
During overlap: 2021-11-07T01:05:53-05:00[US/Central]After overlap(): 2021-11-07T02:05:53-06:00[US/Central]Using withLaterOffsetAtOverlap(): 2021-11-07T01:05:53-06:00[US/Central]