Значения LocalDateTime и ZoneOffset объекта OffsetDateTime различаются при использовании разных методов создания экземпляров.

Создание объектов OffsetDateTime с использованием

  1. ofInstant(Instant, zoneid) или через
  2. свободный интерфейс

может привести к неравным объектам (с помощью утверждений compareTo или сравнения полей ZoneOffset и LocalDateTime), если создание экземпляра через свободный интерфейс пересекает границу перехода на летнее время. Рассмотрим следующий пример:

OffsetDateTime inAMonth = OffsetDateTime.now().plusMonths(1);
OffsetDateTime inAMonth2 = OffsetDateTime.ofInstant(inAMonth.toInstant(), ZoneId.systemDefault());

В центральной Европе (ZoneId 'Europe/Berlin') в середине октября это даст два неравных объекта из-за plusMonths() повторное использование offset первоначального звонка (now()).

Кто-нибудь знает, почему не пересчитывается смещение?

Я столкнулся с этой проблемой во время модульного тестирования, и единственные обходные пути, которые я мог придумать, были: а) не использовать свободный интерфейс или б) воздерживаться от переходов между переходами на летнее время при использовании свободного интерфейса. К сожалению, использование чего-то другого, кроме OffsetDateTime, невозможно.

2 ответа

Кто-нибудь знает, почему не пересчитывается смещение?

Поскольку OffsetDateTime значение, возвращаемое OffsetDateTime.now()не связан с каким-либо конкретным часовым поясом, только смещение. Смещение определяется как "текущее смещение в часовом поясе системы по умолчанию", но после этого нет никакой связи с часовым поясом системы по умолчанию.

Если вы хотите значение, которое имеет связанное с временной зоной, использование ZonedDateTime.now()вместо. Вы можете преобразовать результат ZonedDateTime.now().plusMonths(1) в OffsetDateTime потом:

OffsetDateTime inAMonth = ZonedDateTime.now().plusMonths(1).toOffsetDateTime();

OffsetDateTime.plusMonth никогда не меняет смещение, так как это OffsetDateTime- дата, время с постоянным смещением. Если вы хотите изменить смещение, используйте ZonedDateTime, потому что может измениться только смещение зоны.

При создании OffsetDateTimeоднако, используя момент и зону, очевидно, что необходимо получить смещение указанной зоны в указанный момент. Ну в указанный момент переход на летнее время уже произошел, так что inAMonth2 имеет смещение перехода после перехода на летнее время.

Другие вопросы по тегам