it-swarm.com.ru

В чем разница между Java 8 ZonedDateTime и OffsetDateTime?

Я прочитал документацию, но я все еще не могу понять, когда я должен использовать один или другой:

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

126
Ievgen

Вопрос: В чем разница между Java 8 ZonedDateTime и OffsetDateTime?

Javadocs говорят это:

"OffsetDateTime, ZonedDateTime и Instant все хранят момент времени на временной шкале с точностью до наносекунды. Instant является самым простым, просто представляющим момент. OffsetDateTime добавляет к моменту смещение от UTC/Гринвич, который позволяет получить локальную дату и время. ZonedDateTime добавляет полные правила часовых поясов. "

Источник: https://docs.Oracle.com/javase/8/docs/api/Java/time/OffsetDateTime.html

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

Проще говоря:

Часовой пояс = ( Смещение от UTC + Правила для аномалий)


Q: Согласно документации, OffsetDateTime следует использовать при записи даты в базу данных, но я не понимаю, почему.

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

  • Он может хранить вычисленное смещение ... и извлеченный объект может иметь смещение, которое не согласуется с текущими правилами для идентификатора зоны.

  • Он может отбросить вычисленное смещение ... и тогда извлеченный объект представляет точку на абсолютной/универсальной временной шкале, отличную от той, которая была сохранена.

Если вы используете Java сериализацию объекта, реализация Java 9 выберет первый подход. Возможно, это "более правильный" способ справиться с этим, но это, похоже, не задокументировано. (Драйверы JDBC и привязки ORM, по-видимому, принимают аналогичные решения и, надеюсь, делают это правильно.)

Но если вы пишете приложение, в котором вручную хранятся значения даты/времени или полагаются на Java.sql.DateTime, то справляться со сложностями идентификатора зоны ... вероятно, чего-то следует избегать. Отсюда и совет.

Обратите внимание, что даты, значение/порядок которых нестабилен во времени , могут быть проблемными для приложения. А так как изменения в правилах зон - это крайний случай, проблемы могут возникнуть в неожиданные моменты времени.


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

Теперь это может быть проблемой для любых приложений, которые создают значения ZonedDateTime таким образом. Но с точки зрения того, что кто-то строит корпоративное приложение, это большая проблема, когда (возможно неправильные) значения ZonedDateTime постоянны и используются позже.

157
Stephen C