Diferenças entre a API do Java 8 Date Time (java.time) e o Joda-Time

264

Eu sei que existem perguntas relacionadas ao java.util.Date e Joda-Time. Mas, após algumas pesquisas, não consegui encontrar um tópico sobre as diferenças entre a API java.time (nova no Java 8 , definida pelo JSR 310 ) e o Joda-Time .

Ouvi dizer que a API java.time do Java 8 é muito mais limpa e pode fazer muito mais do que o Joda-Time. Mas não consigo encontrar exemplos comparando os dois.

  • O que o java.time pode fazer com o Joda-Time?
  • O que o java.time pode fazer melhor que o Joda-Time?
  • O desempenho é melhor com o java.time?
Zack
fonte
8
Não é isso que pertence ao Java 7, não ao Java 8. A resposta a essa pergunta foi editada para o Java 8 com muito pouco detalhe. Minha pergunta é especificamente sobre a nova API DateTime do Java 8, não sobre o java.util.Date do Java 7. Estou apenas procurando uma resposta que compara o Java 8 ao JodaTime.
Zack
2
talvez este documento da Oracle possa ajudá-lo.
MarioDS 8/07
Se você possui o Java 7, use a biblioteca adicional; se você possui o Java 8, use a biblioteca interna. Como as duas bibliotecas são basicamente projetadas pela mesma pessoa, não tenho certeza das principais diferenças que você espera.
Peter Lawrey
2
@ PeterLawrey: Joda-Time e a API de data e hora do Java 8 são na verdade bem diferentes.
21413 jarnbjo
5
Você também pode ler esta postagem de blog de Stephen Colbourne - o principal autor de ambos os projetos.
Matt Johnson-Pint

Respostas:

416

Características comuns

a) Ambas as bibliotecas usam tipos imutáveis. O Joda-Time também oferece tipos mutáveis ​​adicionais, como MutableDateTime.

b) Além disso: Ambas as bibliotecas são inspiradas no estudo de design "TimeAndMoney" de Eric Evans ou em idéias de Martin Fowler sobre estilo orientado a domínio, para que se esforcem mais ou menos por um estilo de programação fluente (embora nem sempre seja perfeito ;-)).

c) Nas duas bibliotecas, obtemos um tipo de data do calendário real (chamado LocalDate), um tipo de hora da parede real (chamado LocalTime) e a composição (chamada LocalDateTime). Essa é uma vitória muito grande em comparação com as antigas java.util.Calendare java.util.Date.

d) Ambas as bibliotecas usam uma abordagem centrada no método, o que significa que incentivam o usuário a usar em getDayOfYear()vez de get(DAY_OF_YEAR). Isso causa muitos métodos extras em comparação com java.util.Calendar(embora este último não seja totalmente seguro para o tipo devido ao uso excessivo de ints).

atuação

Veja a outra resposta de @ OO7 apontando para a análise de Mikhail Vorontsov, embora o ponto 3 (captura de exceção) seja provavelmente obsoleto - veja este bug do JDK . O desempenho diferente (que é geralmente a favor do JSR-310 ) deve-se principalmente ao fato de a implementação interna do Joda-Time sempre usar um primitivo longo do tipo máquina-tempo (em milissegundos).

Nulo

O Joda-Time geralmente usa NULL como padrão para o fuso horário do sistema, localidade padrão, carimbo de data / hora atual etc. enquanto o JSR-310 quase sempre rejeita valores NULL.

Precisão

O JSR-310 lida com precisão de nanossegundos, enquanto o Joda-Time é limitado à precisão de milissegundos .

Campos suportados:

Uma visão geral sobre os campos suportados no Java-8 (JSR-310) é fornecida por algumas classes no pacote temporal (por exemplo, ChronoField e WeekFields ), enquanto o Joda-Time é bastante fraco nessa área - consulte DateTimeFieldType . A maior falta de Joda-Time é aqui a ausência de campos relacionados à semana localizados. Um recurso comum do design de implementação de campo é que ambos são baseados em valores do tipo long (nenhum outro tipo, nem mesmo enumerações).

Enum

O JSR-310 oferece enums como DayOfWeekou Monthenquanto o Joda-Time não oferece isso porque foi desenvolvido principalmente nos anos 2002-2004 antes do Java 5 .

API da zona

a) O JSR-310 oferece mais recursos de fuso horário do que o Joda-Time. O Latter não pode fornecer um acesso programático ao histórico de transições de deslocamento de fuso horário, enquanto o JSR-310 é capaz de fazer isso.

b) Para sua informação: JSR-310 mudou seu repositório de fuso horário interno para um novo local e um formato diferente. A pasta da biblioteca antiga lib / zi não existe mais.

Ajustador vs. Propriedade

O JSR-310 introduziu a TemporalAdjusterinterface como uma maneira formalizada de externalizar cálculos e manipulações temporais, especialmente para escritores de bibliotecas ou estruturas. Essa é uma maneira fácil e agradável de incorporar novas extensões do JSR-310 (uma espécie equivalente ao auxiliar estático aulas para ex java.util.Date).

Para a maioria dos usuários, no entanto, esse recurso tem um valor muito limitado, porque o ônus de escrever código ainda é do usuário. As soluções integradas baseadas no novo TemporalAdjusterconceito não são tantas; atualmente, existe apenas a classe auxiliar TemporalAdjusterscom um conjunto limitado de manipulações (e as enumerações Monthou outros tipos temporais).

O Joda-Time oferece um pacote de campo, mas a prática mostrou evidências de que novas implementações de campo são muito difíceis de codificar. Por outro lado, o Joda-Time oferece as chamadas propriedades que tornam algumas manipulações muito mais fáceis e mais elegantes do que no JSR-310, por exemplo, property.withMaximumValue () .

Sistemas de calendário

O JSR-310 oferece 4 sistemas de calendário extras. O mais interessante é o Umalqura (usado na Arábia Saudita). Os outros três são: Minguo (Taiwan), japonês (apenas o calendário moderno desde 1871!) E ThaiBuddhist (correto somente após 1940).

O Joda-Time oferece um calendário islâmico baseado na base de cálculo - não um calendário baseado em avistamento como Umalqura. O tailandês-budista também é oferecido pela Joda-Time de forma semelhante, o Minguo e o japonês não. Caso contrário, o Joda-Time também oferece calendário copta e etiópico (mas sem qualquer apoio à internacionalização).

Mais interessante para os europeus: o Joda-Time também oferece um calendário gregoriano , juliano e misto-gregoriano-juliano. No entanto, o valor prático para cálculos históricos reais é limitado porque recursos importantes como diferentes anos iniciados no histórico de datas não são suportados (a mesma crítica é válida para os antigos java.util.GregorianCalendar).

Outros calendários como hebraica ou persa ou Hindu são completamente ausente nas duas bibliotecas.

Dias da época

O JSR-310 possui a classe JulianFields, enquanto o Joda-Time (versão 2.0) oferece alguns métodos auxiliares na classe DateTimeUtils .

Relógios

O JSR-310 não possui interface (um erro de design), mas uma classe abstrata java.time.Clockque pode ser usada para qualquer injeção de dependência de clock. O Joda-Time oferece a interface MillisProvider e alguns métodos auxiliares no DateTimeUtils . Dessa forma, o Joda-Time também é capaz de suportar modelos orientados a testes com relógios diferentes (zombando etc.).

Duração aritmética

Ambas as bibliotecas suportam o cálculo de distâncias no tempo em uma ou mais unidades temporais. No entanto, ao lidar com durações de unidade única, o estilo JSR-310 é obviamente melhor (e de longa duração em vez de usar int):

JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);

Tempo de Joda => int days = DAYS.daysBetween(date1, date2).getDays();

O manuseio de durações de várias unidades também é diferente. Até os resultados dos cálculos podem diferir - veja este problema fechado do Joda-Time . Enquanto o JSR-310 usa uma abordagem muito simples e limitada para usar apenas as classes Period(duração com base em anos, meses e dias) e Duration(com base em segundos e nanossegundos), o Joda-Time usa uma maneira mais sofisticada de usar a classe PeriodTypepara controlar em que unidades deve ser expressa uma duração (Joda-Time denominada "Período"). Enquanto oPeriodType-API é, de alguma forma, complicado de usar de uma maneira semelhante, não é oferecido pelo JSR-310. Especialmente ainda não é possível no JSR-310 definir durações mistas de data e hora (com base em dias e horas, por exemplo). Portanto, esteja avisado se se trata de migração de uma biblioteca para outra. As bibliotecas em discussão são incompatíveis - apesar dos nomes das mesmas classes parcialmente.

Intervalos

O JSR-310 não suporta esse recurso enquanto o Joda-Time possui suporte limitado. Veja também esta resposta SO .

Formatação e análise

A melhor maneira de comparar as duas bibliotecas é exibir as classes de mesmo nome DateTimeFormatterBuilder (JSR-310) e DateTimeFormatterBuilder (Joda-Time). A variante JSR-310 é um pouco mais poderosa (também pode lidar com qualquer tipo de TemporalFieldcondição, desde que o implementador de campo tenha conseguido codificar alguns pontos de extensão, como resolve () ). Diferença mais importante é no entanto - na minha opinião:

O JSR-310 pode analisar muito melhor os nomes de fuso horário (símbolo de padrão de formato z), enquanto o Joda-Time não conseguiu fazer isso nas versões anteriores e agora apenas de uma maneira muito limitada.

Outra vantagem do JSR-310 é o suporte a nomes de meses independentes, importantes em idiomas como russo ou polonês etc. O Joda-Time não tem acesso a esses recursos - nem mesmo nas plataformas Java-8.

A sintaxe do padrão no JSR-310 também é mais flexível do que no Joda-Time, permite seções opcionais (usando colchetes), é mais orientada ao padrão CLDR e oferece preenchimento (símbolo da letra p) e mais campos.

Caso contrário, deve-se notar que o Joda-Time pode formatar durações usando PeriodFormatter . O JSR-310 não pode fazer isso.


Espero que esta visão geral ajude. Todas as informações coletadas estão lá principalmente devido aos meus esforços e investigações sobre como projetar e implementar uma melhor biblioteca de data e hora (nada é perfeito).

Atualização de 24/06/2015:

Enquanto isso, encontrei tempo para escrever e publicar uma visão geral tabular para diferentes bibliotecas de tempo em Java. As tabelas também contêm uma comparação entre o Joda-Time v2.8.1 e o Java-8 (JSR-310). É mais detalhado que este post.

Meno Hochschild
fonte
12
Este é um post excelente. Muito obrigado por compartilhar todas essas informações. Se tivesse a opção entre Joda e JSR-310 (apenas para casos de uso de baunilha), qual você escolheria? Estou enfrentando essa escolha agora. Estou considerando o JSR-310, apenas porque é mais novo e tento apoiar o "avançar" sempre que possível.
kevinarpe
7
@kevinarpe Se eu tivesse apenas a escolha entre o JSR-310 e o Joda-Time, provavelmente preferiria o JSR-310 porque o Joda-Time quase interrompeu qualquer desenvolvimento (novos grandes recursos não podem ser esperados - apenas correções de bugs e pequenas atualizações). E o design do JSR-310 é simplesmente mais moderno (e com melhor qualidade interna). A propósito, e não surpreende, no entanto, minha decisão real prefere preferir minha própria biblioteca Time4J - veja também o link para a visão geral tabular dada na parte inferior do meu post. É sempre bom ter alternativas e depende muito de quais recursos você precisa.
Meno Hochschild
A versão do Duration Java8 não é um intervalo?
Christian Hujer
1
@ChristianHujer Não, java.time.Durationnão pode ser consultado o início ou o fim, em contraste com um intervalo ancorado em uma linha do tempo. Esse tipo JSR-310 é apenas um par de segundos e nanossegundos decorridos desde um início desconhecido.
Meno Hochschild
42

Data / Hora do Java 8:

  1. As classes Java 8 são construídas em torno do tempo humano. Isso os torna rápidos para a aritmética / conversão de data e hora humana.
  2. Os getters de componentes de data / hora, como a getDayOfMonthcomplexidade O (1), na implementação do Java 8.
  3. A análise de OffsetDateTime/ OffsetTime/ ZonedDateTimeé muito lenta no Java 8 e na b121 devido a exceções lançadas e capturadas internamente no JDK.
  4. Um conjunto de pacotes: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*,java.time.zone.*
  5. Instantes (registros de data e hora) Data e hora Parcial e data parcial do analisador e formatador Fusos horários Diferentes cronologias (calendários).
  6. As classes existentes têm problemas como o Date não tem suporte para I18N ou L10N. Eles são mutáveis!
  7. Mais simples e mais robusto.
  8. Relógios podem ser injetados.
  9. Os relógios podem ser criados com várias propriedades - relógios estáticos, relógios zombados, relógios de baixa precisão (segundos inteiros, minutos inteiros, etc.).
  10. Os relógios podem ser criados com fusos horários específicos. Clock.system(Zone.of("America/Los_Angeles")).
  11. Torna testável a data e hora da manipulação do código.
  12. Faz testes independentemente do fuso horário.

Tempo de Joda:

  1. Joda-Time está usando o tempo da máquina dentro. Uma implementação manual baseada em valores int / long seria muito mais rápida.
  2. Os getters Joda-Time requerem o cálculo do tempo de computador para humano em todas as chamadas getter, o que faz do Joda-Time um gargalo em tais cenários.
  3. Ele é composto por classes imutáveis; ele lida com instantes, data e hora, parciais e durações. É flexível e bem projetado.
  4. Representa datas como instantes. Mas uma data e hora podem corresponder a mais de um instante. Sobrepor a hora em que o horário de verão termina. Além de não ter nenhum instante que corresponda a ele. Hora de intervalo em que a luz do dia começa. Tem que executar cálculos complexos para operações simples.
  5. Aceita valores nulos como valores válidos na maioria de seus métodos. Leva a erros sutis.

Para uma comparação mais detalhada, consulte: -

Desempenho da biblioteca Java 8 Date / Time (assim como Joda-Time 2.3 e juCalendar) . & Nova API de data e hora em Java 8

OO7
fonte
Quando você diz "Faz testes independentemente do fuso horário". O que exatamente você quer dizer com isso?
Zack
@Zack: Provavelmente, se você testar o código, que se comporta de maneira diferente dependendo do fuso horário, pode ser necessário forçar a execução do teste com um fuso horário padrão diferente do fornecido pelo sistema operacional.
21414 jarnbjo
Hah - Eu pensei que você disse que joda correu internamente em uma máquina do tempo , em vez de máquina do tempo ... E eu não ficaria surpreso
Kyranstar
4
@ OO7 O que você quer dizer com 'tempo humano'? O tempo é calculado pelas máquinas de qualquer maneira.
IgorGanapolsky
1

O Joda-Time agora está no modo de manutenção

Não é uma resposta direta à pergunta, mas o projeto Joda-Time não está mais em desenvolvimento ativo. A equipe sugere que os usuários migrem para a API java.time mais recente . Veja o tutorial da Oracle .

Na página oficial do projeto GitHub :

O tempo de Joda não está mais em desenvolvimento ativo, exceto para manter os dados do fuso horário atualizados. A partir do Java SE 8, os usuários são solicitados a migrar para o java.time (JSR-310) - uma parte principal do JDK que substitui esse projeto. Para usuários do Android, java.time é adicionado na API 26+. Projetos que precisam oferecer suporte a níveis mais baixos de API podem usar a biblioteca ThreeTenABP.

Saikat
fonte