Разница между ZonedDateTime и OffsetDateTime

Узнайте больше о классах ZonedDateTime и OffsetDateTime в Java, а также о том, каковы основные различия между этими двумя классами.

1. Понимание идентификатора зоны и смещения зоны

Прежде чем перейти к внутреннему устройству классов, давайте удостоверимся, что мы понимаем разницу между идентификатором зоны и смещениями зоны.

Большинство языков программирования отсчитывают время от определенной точки во времени(называемой эпохой). Например, дата Java представляет собой длинное значение для количества миллисекунд с 00:00(полночь) 1 января 1970 года по UTC(или GMT).

Такие значения не зависят от часового пояса, поскольку в любой момент времени они идентичны в UTC по всей Земле. Но это значение времени может быть преобразовано в любой конкретный сдвиг часового пояса для отображения и обработки.

  • Смещение часового пояса — это разница в часах и минутах между определенным часовым поясом и UTC. Например, значение -08:00 представляет заданное время в часовом поясе, отстающее от UTC на 8 часов.
  • Идентификатор зоны(часовой пояс) — это идентификатор для определенного местоположения или региона, который преобразуется в комбинацию правил для расчета смещения зоны. Часовой пояс может иметь более одного смещения, привязанного к нему в течение года.
    Например, тихоокеанское время не имеет фиксированного смещения относительно UTC; вместо этого смещение меняется в течение года два раза, когда летнее время(DST) ВКЛЮЧЕНО или ВЫКЛЮЧЕНО.

Итак, время UTC с эпохи всегда одинаково в любой момент времени и в части мира. Но когда мы применяем правила часового пояса с летним временем, то момент не является фиксированным числом и перемещается в течение определенной части года в этом часовом поясе.

Например, предположим, что мы переводим часы на один час назад с 2 утра на 1 утра в конце летнего времени. В этом случае 1:30 ночи будет встречаться дважды, что приведет к неоднозначности. OffsetDateTime не учитывает этот случай, а ZonedDateTime учитывает.

2. СмещениеДатыВремени

OffsetDateTime — это неизменяемое представление значения даты-времени с точностью до наносекунды со смещением от UTC/Гринвича в календарной системе ISO-8601. Поскольку оно зависит от смещения, а не от часового пояса, значения смещения не изменяются в соответствии с правилами динамического часового пояса.

Экземпляр OffsetDateTime всегда представляет уникальный момент на временной шкале, поэтому он отлично подходит для случаев, когда нам нужны независимые от часового пояса временные метки. Например, мы можем использовать OffsetDateTime для хранения временных меток в базе данных или отправки значений временных меток в XML-документах по сети.

Класс OffsetDateTime объединяет класс LocalDateTime с классом ZoneOffet. Ниже приведена программа Java для получения текущего времени UTC для сохранения в базе данных.

OffsetDateTime now = OffsetDateTime.now(ZoneOffset.of("UTC"));

3. Зональная дата и время

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

Класс ZonedDateTime, по сути, объединяет класс LocalDateTime с классом ZoneId. Ниже представлена программа Java для получения текущей временной метки, скорректированной с учетом действующего смещения часового пояса в местоположениях в часовом поясе «America/Los_Angeles».

ZonedDateTime now= ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));

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

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

Используйте OffsetDateTime для хранения уникальных моментов в универсальной временной шкале независимо от часовых поясов, например, для хранения временных меток в базе данных или передачи информации в удаленные системы по всему миру.

Используйте ZonedDateTime для отображения временных меток пользователям в соответствии с правилами и смещениями их местного часового пояса.

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

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