1. Обзор
ZonedDateTime
и OffsetDateTime
— довольно популярные классы в Java 8 DateTime
API .
Кроме того, оба сохраняют момент на временной шкале с точностью до наносекунд .
И поначалу может возникнуть путаница при выборе между ними.
В этом кратком руководстве мы рассмотрим различия между ZonedDateTime
и OffsetDateTime
.
2. Зонированная дата и время
ZonedDateTime — это неизменное представление даты и времени с часовым поясом
в календарной системе ISO-8601, например 2007-12-03T10:15:30+01:00 Europe/Pari
s. Он содержит состояние, эквивалентное трем отдельным объектам: LocalDateTime
, ZoneId
и разрешенному ZoneOffset
.
Здесь ZoneId
определяет, как и когда изменяется смещение. Таким образом, смещение не может быть свободно установлено, так как зона определяет, какие смещения действительны.
Чтобы получить текущее ZonedDateTime
для определенного региона, мы будем использовать:
ZoneId zone = ZoneId.of("Europe/Berlin");
ZonedDateTime zonedDateTime = ZonedDateTime.now(zone);
Класс ZonedDateTime
также предоставляет встроенные методы для преобразования заданной даты из одного часового пояса в другой:
ZonedDateTime destZonedDateTime = sourceZonedDateTime.withZoneSameInstant(destZoneId);
Наконец, он полностью поддерживает переход на летнее время и корректирует летнее время. Это часто бывает удобно, когда мы хотим отобразить поле даты и времени в определенном часовом поясе.
3. СмещениеДатыВремя
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
, не изменит значение даты.
Давайте быстро суммируем ключевые различия.
Зонеддатетиме
:
- хранит все поля даты и времени с точностью до наносекунд и часовой пояс со смещением зоны, используемым для обработки неоднозначных локальных дат и времени.
- нельзя свободно устанавливать смещения, так как зона контролирует допустимые значения смещения
- полностью поддерживает летнее время и корректирует летнее время
- пригодится для отображения полей даты и времени в пользовательском часовом поясе
СмещениеДатеВремя
:
- сохраняет все поля даты и времени с точностью до наносекунд, а также смещение от GMT/UTC (без информации о часовом поясе)
- следует использовать для хранения даты в базе данных или передачи ее по сети
5. Вывод
В этом руководстве мы рассмотрели различия между ZonedDateTime
и OffsetDateTime
.
Как обычно, полный исходный код доступен на Github .