Qual é a diferença entre ZonedDateTime e OffsetDateTime?

155

Eu li a documentação, mas ainda não consigo entender quando devo usar um ou outro:

De acordo com a documentação, OffsetDateTimedeve ser usado ao escrever a data no banco de dados, mas não entendo o porquê.

Zhenya
fonte
4
Basicamente, ZonedDateTimetambém contém informações sobre fusos horários, incluindo a alternância de horário de verão etc. do que eu li.
fge 14/05

Respostas:

187

P: Qual é a diferença entre java 8 ZonedDateTime e OffsetDateTime?

Os javadocs dizem o seguinte:

" OffsetDateTime, ZonedDateTimeE Instanttoda a loja de um instante no tempo-line a precisão de nanossegundos. InstantÉ o mais simples, simplesmente representar o instante. OffsetDateTimeContribui para o instante em que o deslocamento do UTC / Greenwich, o que permite ser obtido a data-hora local. ZonedDateTimeAdiciona tempo integral regras da zona ".

Fonte: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html

Portanto, a diferença entre OffsetDateTimee ZonedDateTimeé que o último inclui as regras que cobrem os ajustes do horário de verão e várias outras anomalias.

Em poucas palavras:

Fuso Horário = ( Deslocamento a partir do UTC + Regras para Anomalias)


P: De acordo com a documentação, OffsetDateTimedeve ser usado ao escrever a data no banco de dados, mas não entendo o motivo.

As datas com compensações da hora local sempre representam os mesmos instantes no tempo e, portanto, têm uma ordem estável. Por outro lado, o significado de datas com informações completas do fuso horário é instável diante dos ajustes nas regras dos respectivos fusos horários. (E isso acontece; por exemplo, para valores de data e hora no futuro.) Portanto, se você armazenar e recuperar um, ZonedDateTimea implementação tem um problema:

  • Ele pode armazenar o deslocamento computado ... e o objeto recuperado pode ter um deslocamento inconsistente com as regras atuais para o ID da zona.

  • Ele pode descartar o deslocamento computado ... e o objeto recuperado representa um ponto diferente na linha do tempo absoluto / universal do que aquele que foi armazenado.

Se você usar a serialização de objeto Java, a implementação do Java 9 adotará a primeira abordagem. Esta é sem dúvida a maneira "mais correta" de lidar com isso, mas isso não parece estar documentado. (Drivers JDBC e ligações ORM provavelmente estão tomando decisões semelhantes e, espero, estão acertando.)

Mas se você estiver escrevendo um aplicativo que armazena manualmente valores de data / hora ou que dependem disso java.sql.DateTime, lidar com as complicações de um ID de zona é ... provavelmente algo a ser evitado. Daí o conselho.

Observe que datas cujo significado / ordem é instável ao longo do tempo pode ser problemático para um aplicativo. E como as alterações nas regras de zona são um caso de ponta, os problemas podem surgir em momentos inesperados.


Uma (possível) segunda razão para o conselho é que a construção de a ZonedDateTimeé ambígua em determinados pontos. Por exemplo, no período em que você está "colocando os relógios de volta", a combinação de um horário local e um ID de zona pode fornecer duas compensações diferentes. O ZonedDateTimeconsistentemente escolherá um sobre o outro ... mas essa nem sempre é a escolha correta.

Agora, isso pode ser um problema para qualquer aplicativo que construa ZonedDateTimevalores dessa maneira. Mas da perspectiva de alguém criar um aplicativo corporativo, é um problema maior quando os valores (possivelmente incorretos) ZonedDateTimesão persistentes e usados ​​posteriormente.

Stephen C
fonte