Qual é a diferença entre Instant e LocalDateTime?

Eu sei disso:

  • Instant é, em vez disso, uma representação de registro de data e hora “técnica” (nanossegundos) para computação.
  • LocalDateTime é uma representação de data / hora, incluindo fusos horários para humanos.

Ainda no final, o IMO pode ser considerado como um tipo para a maioria dos casos de uso de aplicativos. Como exemplo: Atualmente estou executando um trabalho em lotes onde preciso calcular uma próxima execução com base em datas e estou lutando para encontrar um prós / contras entre esses dois tipos (além da vantagem de precisão de nanossegundos do Instant e da parte do fuso horário de LocalDateTime).

Você pode citar alguns exemplos de aplicativos, onde somente Instant ou LocalDateTime devem ser usados?

Editar: Cuidado com as interpretações erradas do LocalDateTime em relação à precisão e ao fuso horário

Presunção Incorreta

LocalDateTime é uma representação de data / hora, incluindo fusos horários para humanos.

Sua declaração está incorreta: um LocalDateTime não tem fuso horário . Não ter fuso horário é o ponto inteiro dessa class.

Para citar o documento dessa class:

Esta class não armazena ou representa um fuso horário. Em vez disso, é uma descrição da data, como usada para aniversários, combinada com a hora local, como visto em um relógio de parede. Ele não pode representar um instante na linha do tempo sem informações adicionais, como um deslocamento ou fuso horário.

Então Local… significa “não zoneado”.

Instante

insira a descrição da imagem aqui

Um Instant é um momento na linha do tempo em UTC , uma contagem de nanossegundos desde a época do primeiro momento de 1970 UTC (basicamente, veja o documento de class para detalhes essenciais). Como a maior parte de sua lógica de negócios, armazenamento de dados e troca de dados deve estar no UTC, essa é uma class prática a ser usada com frequência.

 Instant instant = Instant.now() ; // Capture the current moment in UTC. 

ZoneId

insira a descrição da imagem aqui

Um ZoneId é um fuso horário .

Um fuso horário é um deslocamento de tantas horas e minutos do UTC. Um novo dia amanhece mais cedo em Paris do que em Montreal , por exemplo. Então, precisamos mover as mãos do relógio para refletir melhor o meio-dia (quando o Sol está diretamente acima) para uma determinada região. Quanto mais longe leste / oeste da linha UTC na Europa Ocidental / África, maior o deslocamento.

Além disso, um fuso horário é um conjunto de regras para lidar com ajustes e anomalias praticados por uma comunidade ou região local. A anomalia mais comum é a loucura muito popular conhecida como Daylight Saving Time (DST) .

Um fuso horário tem o histórico de regras passadas, regras atuais e regras confirmadas para o futuro próximo.

Essas regras mudam com mais frequência do que você poderia esperar. Certifique-se de manter as regras da biblioteca de data e hora, geralmente uma cópia do database ‘tz’ , atualizadas. Manter-se atualizado é agora mais fácil do que nunca no Java 8 com o Oracle lançando uma ferramenta de atualização do fuso horário .

Use nomes de fuso horário adequados . Estes nomes assumem a forma de continente mais um SLASH mais uma cidade ou região. Evite os códigos de 3 a 4 letras, como EST ou IST . Eles não são nem padronizados nem únicos. Eles ainda confundem a bagunça do DST.

Fuso Horário = Offset + Regras de Ajustes

 ZoneId z = ZoneId.of( “Africa/Tunis” ) ; 

Às vezes temos apenas um deslocamento sem as regras. Java fornece o ZoneOffset para essa finalidade, uma subclass de ZoneId . Observe a constante útil definida lá, ZoneOffset.UTC .

 ZoneOffset offset = ZoneOffset.of( -5 , 0 ) ; // “-05:00” 

ZonedDateTime

insira a descrição da imagem aqui

Pense em ZonedDateTime conceitualmente como um Instant com um ZoneId atribuído.

ZonedDateTime = (Instantâneo + ZoneId)

Quase todo o seu back-end, database, lógica de negócios, persistência de dados, troca de dados devem estar em UTC. Mas, para apresentação aos usuários, você precisa se ajustar a um fuso horário esperado pelo usuário. Esse é o objective da class ZonedDateTime e das classs do formatador usadas para gerar representações String desses valores de data e hora.

 ZonedDateTime zdt = instant.atZone( z ) ; 

LocalDateTime, LocalDate, LocalTime

insira a descrição da imagem aqui

As classs de hora de data “local”, LocalDateTime , LocalDate , LocalTime , são um tipo diferente de criatura. Não estão vinculados a nenhuma localidade ou fuso horário. Eles não estão vinculados à linha do tempo. Eles não têm nenhum significado real até que você os aplique a uma localidade para encontrar um ponto na linha do tempo.

Por exemplo, “O natal começa à meia-noite do dia 25 de dezembro de 2015” é um LocalDateTime . A meia-noite bate em diferentes momentos em Paris do que em Montreal e novamente em Seattle e em Auckland .

 LocalDate ld = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ; LocalTime lt = LocalTime.MIN ; // 00:00:00 LocalTime ldt = LocalDateTime.of( ld , lt ) ; // Xmas morning anywhere. 

Outro exemplo, “A Acme Company tem uma política de que a hora do almoço começa às 12h30 em cada uma de suas fábricas em todo o mundo” é um LocalTime . Para ter um significado real, você precisa aplicá-lo na linha do tempo para descobrir o momento das 12:30 na fábrica de Stuttgart ou 12:30 na fábrica de Rabat ou 12:30 na fábrica de Sydney .

Portanto, para aplicativos de negócios, os tipos “locais” não são usados ​​com frequência, pois representam apenas a ideia geral de uma possível data ou hora, e não um momento específico na linha do tempo. Os aplicativos de negócios tendem a se preocupar com o momento exato em que uma fatura chegou, um produto enviado para transporte, um funcionário foi contratado ou o táxi saiu da garagem. Então, os desenvolvedores de aplicativos de negócios usam Instant e ZonedDateTime quase exclusivamente. Por outro lado, você deve considerar usar os tipos Local… para reservar events futuros (ex: consultas ao dentista) longe o suficiente no futuro, onde você corre o risco de os políticos refinarem o fuso horário com pouco aviso prévio, como costumam fazer.


Sobre o java.time

O framework java.time está embutido no Java 8 e posterior. Essas classs substituem as antigas classs herdadas de data e hora legadas , como java.util.Date , Calendar e SimpleDateFormat .

O projeto Joda-Time , agora em modo de manutenção , aconselha a migration para as classs java.time .

Para saber mais, veja o Oracle Tutorial . E pesquise o Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

Você pode trocar objects java.time diretamente com seu database. Use um driver JDBC compatível com o JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de classs java.sql.* .

Onde obter as classs java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 e posterior
    • Construídas em.
    • Parte da API Java padrão com uma implementação integrada.
    • O Java 9 adiciona alguns resources e correções menores.
  • Java SE 6 e Java SE 7
    • Grande parte da funcionalidade java.time é transferida para o Java 6 e 7 no ThreeTen-Backport .
  • Android
    • Versões posteriores das implementações do pacote Android das classs java.time.
    • Para Android anterior (<26), o projeto ThreeTenABP adapta o ThreeTen-Backport (mencionado acima). Veja Como usar o ThreeTenABP… .

O projeto ThreeTen-Extra estende java.time com classs adicionais. Este projeto é um campo de testes para possíveis futuras adições ao java.time. Você pode encontrar algumas classs úteis aqui como Interval , YearWeek , YearQuarter e muito mais .

Uma diferença principal é a parte Local de LocalDateTime . Se você mora na Alemanha e cria uma instância LocalDateTime e outra pessoa mora nos EUA e cria outra instância no mesmo momento (desde que os relógios estejam configurados corretamente) – o valor desses objects seria realmente diferente. Isso não se aplica ao Instant , que é calculado independentemente do fuso horário.

LocalDateTime armazena data e hora sem fuso horário, mas seu valor inicial é dependente de fuso horário. Instant não é.

Além disso, o LocalDateTime fornece methods para manipular componentes de data como dias, horas e meses. Um Instant não.

Além da vantagem de precisão nanossegundo do Instant e da parte do fuso horário do LocalDateTime

Ambas as classs têm a mesma precisão. LocalDateTime não armazena o fuso horário. Leia o javadocs completamente, porque você pode cometer um grande erro com tais suposições inválidas: Instant e LocalDateTime .

Você está errado sobre LocalDateTime : ele não armazena informações de fuso horário e tem precisão de nanossegundos. Citando o Javadoc (ênfase minha):

Uma data e hora sem fuso horário no sistema de calendar ISO-8601 , como 2007-12-03T10: 15: 30.

LocalDateTime é um object de data e hora imutável que representa uma data e hora, geralmente vista como ano-mês-dia-hora-minuto-segundo. Outros campos de data e hora, como dia da semana, dia da semana e semana do ano, também podem ser acessados. O tempo é representado para uma precisão de nanossegundos . Por exemplo, o valor “2 de outubro de 2007 às 13: 45.30.123456789” pode ser armazenado em um LocalDateTime.

A diferença entre os dois é que Instant representa um deslocamento da Epoch (01-01-1970) e, como tal, representa um determinado instante na linha do tempo. Dois objects Instant criados no mesmo momento em dois lugares diferentes da Terra terão exatamente o mesmo valor.

Instant corresponde ao tempo no meridiano principal (Greenwich).

Considerando LocalDateTime relação às configurações de fuso horário do sistema operacional e

não pode representar um instante sem informações adicionais, como um deslocamento ou fuso horário.