Сравнение двух экземпляров ZonedDateTime

Научитесь сравнивать два экземпляра 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]

Исходный код на Github

Прокрутить вверх