В чем разница между java 8 ZonedDateTime и OffsetDateTime?
Я прочитал документацию, но я все еще не могу понять, когда я должен использовать один или другой:
OffsetDateTime
ZonedDateTime
Согласно документации OffsetDateTime
следует использовать при записи даты в базу данных, но я не понимаю, почему.
2 ответа
Javadocs говорят это:
"
OffsetDateTime
,ZonedDateTime
а такжеInstant
все хранят мгновение на временной шкале с точностью до наносекунды.Instant
самый простой, просто представляющий момент.OffsetDateTime
добавляет к моменту смещение от UTC/ Гринвич, что позволяет получить местную дату и время.ZonedDateTime
добавляет полные правила часовых поясов."
Источник: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html
Таким образом, разница между OffsetDateTime
а также ZonedDateTime
является то, что последний включает в себя правила, которые охватывают переход на летнее время.
OffsetDateTime следует использовать при записи даты в базу данных, но я не понимаю, почему.
Одна из причин заключается в том, что даты со смещением по местному времени всегда представляют одни и те же моменты времени и, следовательно, имеют стабильный порядок. В отличие от этого, значение дат с полной информацией о часовом поясе является нестабильным ввиду изменений в правилах для соответствующих часовых поясов. (И это случается...)
Даты, значение / порядок которых нестабильны, проблематичны, если (например) вы создаете индекс базы данных для поля даты.
Принятый ответ дает очень подробное объяснение, возможно, приведенный ниже пример кода может предоставить вам короткую и четкую картину:
Instant instant = Instant.now();
Clock clock = Clock.fixed(instant, ZoneId.of("America/New_York"));
OffsetDateTime offsetDateTime = OffsetDateTime.now(clock);
ZonedDateTime zonedDateTime = ZonedDateTime.now(clock);
System.out.println(offsetDateTime); // 2019-01-03T19:10:16.806-05:00
System.out.println(zonedDateTime); // 2019-01-03T19:10:16.806-05:00[America/New_York]
System.out.println();
OffsetDateTime offsetPlusSixMonths = offsetDateTime.plusMonths(6);
ZonedDateTime zonedDateTimePlusSixMonths = zonedDateTime.plusMonths(6);
System.out.println(offsetPlusSixMonths); // 2019-07-03T19:10:16.806-05:00
System.out.println(zonedDateTimePlusSixMonths); // 2019-07-03T19:10:16.806-04:00[America/New_York]
System.out.println(zonedDateTimePlusSixMonths.toEpochSecond() - offsetPlusSixMonths.toEpochSecond()); // -3600
System.out.println();
System.out.println(zonedDateTimePlusSixMonths.toLocalDateTime()); // 2019-07-03T19:10:16.806
System.out.println(offsetPlusSixMonths.toLocalDateTime()); // 2019-07-03T19:10:16.806
Короче говоря, используйте только в том случае, если вы хотите учитывать летнее время, обычно разница в один час, как вы можете видеть в примере выше, смещение
ZonedDateTime
меняться от
-5:00
к
-04:00
, в большинстве случаев ваша бизнес-логика может закончиться ошибкой.
(копия кода с https://www.youtube.com/watch?v=nEQhx9hGutQ)