Stephen Colebourne, líder da JSR 310, a nova API de Date and Time do Java, publicou recentemente um rascunho com algumas adições e mudanças propostas para a linguagem Java. InfoQ entrevistou Stephen na QCon Londres para descobrir mais detalhes sobre o projeto.
InfoQ: Por que nós precisamos de uma nova API de Date and Time? Qual é o problema com a que já existe?
Stephen: O principal problema com as atuais APIs(java.util.Date
and java.util.Calendar
) é que elas são mutáveis. Em outras palavras, considere o seguinte:
public class Employee { private final Date startDate; public Employee(Date date) { startDate = date; } public Date getDate() { return startDate; } }
Mesmo que o atributo startDate
esteja marcado como final
, a instância retornada java.util.Date
é mutável, por isso é possível externamente alterar o atributo startDate
chamando o método setYear()
. Existem muitos outros pequenos problemas, tais como o ano começar a partir de 1900 e os meses em 0, mas o problema principal é a mutabilidade. E isso é algo que não pode ser corrigido nas atuais APIs.
InfoQ: O que é equivalente ao java.util.Date
na JSR 310?
Stephen:Existem na verdade dois conceitos de datas na JSR 310. O primeiro é o Instant
, que corresponde grosseiramente a classe java.util.Date,
em que ele representa um ponto fixo no tempo como um deslocamento da data padrão para o Java (1º de Janeiro de 1970). Diferente da classe java.util.Date
, esta tem a precisão de nanosegundos.
O segundo corresponde ao conceitos mais humanos, como LocalDate
and LocalTime
. Estas representam o time-zone geral com o conceito de um dia (sem um componente de tempo) ou tempo (sem um componente de dia), é similar as representações do java.sql
. Outro exemplo é MonthDay
que pode armazenar o dia do aniversário de alguém sem o ano. Cada uma destas classes guarda a data correta internamente, ao invés do clássico hack da java.util.Date
onde midnight é usado para datas e 01-01-1970 é usado para tempos.
InfoQ: Você mencionou o árduo conceito de time zones. O que a nova API fará a respeito disso?
Stephen:A primeira coisa para separar são as diferenças entre um time zone(como Europa/Paris ou America/Nova Iorque) e o offset do UTC, como +01:00 e -08:00. Um offset é simplesmente a diferença entre o UTC e o tempo local, enquanto que o time zone é um conjunto de regras nomeados que descreve como os offset mudam ao longo do tempo. Por exemplo, o time zone descreverá que a região específica, como Nova Iorque, terá um offset num dado instante, e outro offset em outro instante (por exemplo no horário de verão).
Existem três níveis de classes para suportar estes conceitos. LocalDateTime
permite datas serem representadas sem um offset ou time zone. OffsetDateTime
adicionalmente específica o offset enquanto a classe ZonedDateTime
adiciona as regras do time zone. No passado, muitas aplicações eram obrigadas a usar time zones quando todas elas na verdade precisavam de offsets. Um exemplo disso é a especificação do Schema do XML que somente suporta offsets e não time zones. Com a JSR 310 esta diferença poderá ser expressada.
Por fim, as regras de time zones mudam constantemente. Como as mudanças nos horários de verão. Por exemplo, nos Estados Unidos recentemente foi resgatado seu horário de verão, então agora é horário de verão nos Estados Unidos mas não na Europa. Existem algumas que mudam todo ano, como no Brasil. A JSR 310 API permite que os time zones sejam versionados, e consequentemente substituídos, com novas versões dos dados do time zone. Embora a substituição seja deixada para implementações específicas, seria possível criar novas regras para uma VM existente simplesmente prefixando o classpath com os novos dados, ao invés de ter que atualizar a instalação da JVM.
InfoQ: E quanto aos intervalos entre uma data inicial e uma data final?
Stephen:É possivel representar um intervalo entre dois Instants
usando a classe Duration
. Para a maioria dos códigos que usam uma data final e uma data inicial, esta é a comparação mais próxima.
Como foi mencionado antes, existem alguns conceitos específicos para representar um YearMonth
e MonthDay
, que devem ser usados quando for apropriado. Existem também um conceito de Period
que pode ser usado para representar qualquer período de tempo, como "dois anos, três meses, sete dias, quatro horas, cinquenta minutos".
InfoQ: E quanto a outros calendários?
Stephen: O calendário principal é o calendário ISOChronology
, que é o padrão e usado para mapear tempos assim como GregorianCalendar
faz atualmente nas APIs do Java. Entretanto, existe também suporte outros cronologias, como CopticChronology
e ThaiBuddhistChronology
, com a possibilidade de adicionar outros conforme forem solicitados.
InfoQ: Alguns destes conceitos já existem e foram explorados no JodaTime. Qual é a relação entre ele e a JSR 310?
Stephen: JodaTime já foi usados por muitos desenvolvedores, mas é melhor para todos tê-lo como base no Java. A maior mudança e mais óbvia é quanto ao nome do package (de org.joda.time
para javax.time
), mas na prática existem algumas sutis mudanças.
Em primeiro lugar, null
era aceito pela API do Joda Time para referenciar um tempo ou duração 0. Embora tentador, isto pode resultar em um número sutil de erros. A JSR 310 corrige isso retornando uma exceção quando argumentos null
são usados.
Em segundo lugar, a diferença entre os tempos relacionados ao computador (Instant
) e tempos relacionados aos humanos (DateTime
) tem sido mais aparentes. A interface InstantProvider
substitui a antiga ReadableInstant
, para prover uma maneira de converter qualquer tempo em um Instant.
Em terceiro lugar, todas exceções lançadas são agora subtipos de CalendricalExcpetion
. Embora uma RuntimeException
, esta é uma classe mãe que pode ser tratada pelos clientes.
InfoQ: Finalmente, qual é o status atual da JSR 310?
Stephen: O expert group da JSR 310 opera uma mailing list aberta, e a revisão foi publicada três semana atrás. O fim do período de revisões é dia 28 de março de 2010; então se você tem algum comentário, por favor dirija ele para a mailing list dev@jsr-310.dev.java.net, ou comente diretamente no Expert Draft Review wiki.
Depois de muito tempo será que finalmente a API de Date and Time sai do forno?