Freqüentemente, encontro comentários negativos sobre Java Date
e outras classes relacionadas a datas. Sendo um desenvolvedor .NET, não consigo entender totalmente (sem tê-los usado) o que há de errado com eles.
Alguem pode iluminar isso?
Freqüentemente, encontro comentários negativos sobre Java Date
e outras classes relacionadas a datas. Sendo um desenvolvedor .NET, não consigo entender totalmente (sem tê-los usado) o que há de errado com eles.
Alguem pode iluminar isso?
Respostas:
Ah, a Date
classe Java . Talvez um dos melhores exemplos de como não fazer algo em qualquer idioma, em qualquer lugar. Por onde começo?
Ler o JavaDoc pode levar alguém a pensar que os desenvolvedores realmente têm algumas boas idéias. Ele continua sobre a diferença entre UTC e GMT , apesar do fato de que a diferença entre os dois é basicamente segundos bissextos (o que acontece muito raramente ).
No entanto, as decisões de design realmente desperdiçam qualquer ideia de ser uma API bem projetada. Aqui estão alguns dos erros favoritos:
null
. Como resultado, temos 0..11 (e hoje sendo o mês 11 do ano 109). Há um número semelhante de ++ e - nos meses para converter em string.Calendar
, projetado para 'consertar' isso, na verdade comete os mesmos erros. Eles ainda são mutáveis.Date
representa a DateTime
, mas para diferir para aqueles no terreno do SQL, há outra subclasse java.sql.Date
, que representa um único dia (embora sem um fuso horário associado a ele).TimeZone
s associados a um Date
e, portanto, os intervalos (como um 'dia inteiro') são frequentemente representados como meia-noite a meia-noite (geralmente em algum fuso horário arbitrário)Por fim, é importante notar que os segundos bissextos geralmente se corrigem em relação a um bom relógio do sistema, que é atualizado com ntp em uma hora (veja os links abaixo). A chance de um sistema ainda estar ativo e em execução na introdução de dois segundos bissextos (a cada seis meses no mínimo, praticamente a cada poucos anos) é bastante improvável, especialmente considerando o fato de que você precisa reimplantar novas versões de seu código de vez em quando . Mesmo o uso de uma linguagem dinâmica que regenera classes ou algo como um mecanismo WAR poluirá o espaço da classe e acabará sem permgen.
JSR 310 , que suplantou as antigas classes de data e hora com java.time no Java 8, se justifica no JSR original da seguinte maneira:
2.5 Que necessidade da comunidade Java será atendida pela especificação proposta?
Atualmente Java SE tem duas APIs de data e hora separadas - java.util.Date e java.util.Calendar. Ambas as APIs são consistentemente descritas como difíceis de usar por desenvolvedores Java em weblogs e fóruns. Notavelmente, ambos usam um índice zero por meses, o que é a causa de muitos bugs. O Calendar também sofreu com muitos bugs e problemas de desempenho ao longo dos anos, principalmente devido ao armazenamento interno de seu estado de duas maneiras diferentes.
Um bug clássico (4639407) impedia que certas datas fossem criadas em um objeto Calendário. Pode ser escrita uma sequência de código que pode criar uma data em alguns anos, mas não em outros, tendo o efeito de impedir que alguns usuários insiram suas datas de nascimento corretas. Isso foi causado pela classe Calendar permitindo apenas um ganho de horário de verão de uma hora no verão, quando historicamente era mais 2 horas em torno da época da segunda guerra mundial. Embora esse bug agora tenha sido corrigido, se em algum ponto no futuro um país optasse por introduzir um ganho de horário de verão de mais três horas no verão, a classe Calendário seria novamente quebrada.
A API Java SE atual também sofre em ambientes multithread. As classes imutáveis são conhecidas por serem inerentemente thread-safe, pois seu estado não pode ser alterado. No entanto, tanto a data quanto o calendário são mutáveis, o que exige que os programadores considerem a clonagem e o encadeamento explicitamente. Além disso, a falta de segurança de thread em DateTimeFormat não é amplamente conhecida e tem sido a causa de muitos problemas de threading difíceis de rastrear.
Assim como os problemas com as classes que o Java SE possui para datetime, ele não possui classes para modelar outros conceitos. Datas ou horas fora do fuso horário, durações, períodos e intervalos não têm representação de classe em Java SE. Como resultado, os desenvolvedores frequentemente usam um int para representar uma duração de tempo, com javadoc especificando a unidade.
A falta de um modelo abrangente de data e hora também faz com que muitas operações comuns sejam mais complicadas do que deveriam. Por exemplo, calcular o número de dias entre duas datas é um problema particularmente difícil no momento.
Este JSR resolverá o problema de um modelo completo de data e hora, incluindo datas e horas (com e sem fusos horários), durações e períodos de tempo, intervalos, formatação e análise.
getMonth()
é baseado em zero, getYear()
é baseado em 1900 (ou seja, o ano de 2009 é representado como 109).Date
classe.Sinto por você ... como ex-programador .NET, fiz as mesmas perguntas, a API de tempo em .NET (timespans, sobrecarga de operador) é muito conveniente.
Primeiro, para criar uma data específica, você usa uma API obsoleta ou:
Calendar c = Calendar.getInstance();
c.set(2000, 31, 12)
Para subtrair um dia você faz coisas más como
Date firstDate = ...
Calendar c = Calendar.getInstance();
c.setTime(fistDate);
c.add(Calendar.DATE,-1);
Date dayAgo = c.getTime();
ou pior
Date d = new Date();
Date d2 = new Date(d.getTime() - 1000*60*60*24);
Para saber quanto tempo se passou entre duas datas (em dias / semanas / meses) ... fica ainda pior
No entanto, DateUtils de apache ( org.apache.commons.lang.time.DateUtils
) oferece alguns métodos convenientes e eu me descobri usando apenas eles recentemente
Como escreveu Brabster, Joda Time também é uma boa biblioteca externa, mas o apache parece mais "comum" do que qualquer outra coisa ...
Period
e Duration
para calcular e representar o tempo decorrido em uma escala de anos-meses-dias e horas-minutos-segundos, respectivamente.
Acho que a API Date do Java pode ser usada, para ser honesto. A maioria das questões que eu vi e ouvi sobre se relacionam com a verbosidade, a necessidade de envolver várias classes para fazer algo útil ( Calendar
, Date
, DateFormat
/ SimpleDateFormat
) ea falta de assessores simples como getDayOfWeek()
.
Joda Time é uma API alternativa bem respeitada em Java, e na seção Why Joda Time ele fornece mais alguns argumentos sobre porque é uma alternativa viável que pode ser de interesse.