«1. Обзор

ZonedDateTime и OffsetDateTime — довольно популярные классы в Java 8 DateTime API. Кроме того, оба сохраняют момент на временной шкале с точностью до наносекунд. И поначалу может возникнуть путаница при выборе между ними.

В этом кратком руководстве мы рассмотрим различия между ZonedDateTime и OffsetDateTime.

2. ZonedDateTime

ZonedDateTime — это неизменное представление даты и времени с часовым поясом в календарной системе ISO-8601, например 2007-12-03T10:15:30+01:00 Europe/Paris. Он содержит состояние, эквивалентное трем отдельным объектам: LocalDateTime, ZoneId и разрешенному ZoneOffset.

Здесь ZoneId определяет, как и когда изменяется смещение. Таким образом, смещение не может быть свободно установлено, так как зона определяет, какие смещения действительны.

Чтобы получить текущую ZonedDateTime для определенного региона, мы будем использовать:

ZoneId zone = ZoneId.of("Europe/Berlin");
ZonedDateTime zonedDateTime = ZonedDateTime.now(zone);

Класс ZonedDateTime также предоставляет встроенные методы для преобразования заданной даты из одного часового пояса в другой:

ZonedDateTime destZonedDateTime = sourceZonedDateTime.withZoneSameInstant(destZoneId);

Наконец, он полностью поддерживает переход на летнее время и корректирует летнее время. Это часто бывает удобно, когда мы хотим отобразить поле даты и времени в определенном часовом поясе.

3. OffsetDateTime

OffsetDateTime — это неизменное представление даты и времени со смещением от UTC/Greenwich в календарной системе ISO-8601, например 2007-12-03T10:15:30+01:00. . Другими словами, он хранит все поля даты и времени с точностью до наносекунд, а также смещение от GMT/UTC.

Получим текущее значение OffsetDateTime с двухчасовым смещением от GMT/UTC:

ZoneOffset zoneOffSet= ZoneOffset.of("+02:00");
OffsetDateTime offsetDateTime = OffsetDateTime.now(zoneOffSet);

4. Основные отличия

Во-первых, не имеет смысла (без преобразований) напрямую сравнить две даты с полной информацией о часовом поясе. Поэтому мы всегда должны предпочитать хранить OffsetDateTime в базе данных, а не ZonedDateTime, поскольку даты со смещением местного времени всегда представляют одни и те же моменты времени.

Более того, в отличие от ZonedDateTime, добавление индекса к столбцу, в котором хранится OffsetDateTime, не изменит значение даты.

Давайте быстро суммируем ключевые отличия.

ZonedDateTime:

    сохраняет все поля даты и времени с точностью до наносекунд, а часовой пояс со смещением зоны, используемым для обработки неоднозначных локальных дат и времени, не может свободно устанавливать смещения, поскольку зона контролирует допустимые значения смещения полностью учитывают летнее время и обрабатывают корректировки перехода на летнее время; это удобно для отображения полей даты и времени в пользовательском часовом поясе

OffsetDateTime:

    сохраняет все поля даты и времени с точностью до наносекунд, а также поскольку смещение от GMT/UTC (без информации о часовом поясе) следует использовать для хранения даты в базе данных или передачи ее по сети

5. Заключение

В этом руководстве мы рассмотрели различия между ZonedDateTime и СмещениеДатыВремя.

Как обычно, полный исходный код доступен на Github.