sábado, 28 de março de 2015

It's Time!

Quem nunca xingou o Java ao ter que lidar com datas que atire a primeira a pedra! Apesar das muitas críticas, a API de Datas sofreu pouca, ou quase nenhuma, alteração desde a sua criação. No Java 1.0 existia apenas a classe java.util.Date, que era muito simplista, tanto que teve a maioria de seus métodos depreciados no Java 1.1, quando surgiu a classe Calendar.

Mesmo com Calendar, a API ainda apresentava alguns problemas de design, tais como, o ano de Date começando em 1900, meses começando em 1 e dias começando 0. Junte isso ao fato de as classes não serem thread-safe, levando a um potencial surgimento de comportamentos estranhos em ambientes concorrentes. Por fim, os objetos gerados a partir de calendar são mutáveis, permitindo alterações indesejadas, como as do exemplo abaixo:


Pra contornar esses problemas, muitos desenvolvedores optavam por escrever suas próprias classes pra lidar com data. Nessa meio tempo, surgiu uma das bibliotecas que foi a base para a construção da nova API de Data, a Joda-Time. Stephen Colebourne, criador da Joda-Time, é um dos líderes da JSR-310, base para especificação da nova API de Date/Time.

Dentre as principais mudanças da nova API, podemos destacar:
  • Imutabilidade das classes
  • Classes Thread-safe
  • Melhor design de classes, com domínios bem definidos
  • Separação de cronologias
As classes da nova API foram colocadas em um novo pacote: java.time. Ao todo, foram criadas 15 novas classes, além de uma nova classe para exceções e três novos enums. Como já é marca do Java, a compatibilidade com as versões antigas foi mantida, e as classes da API antiga ganharam novos métodos que interagem com a API nova. 

Para uma melhor didática e separação, iremos abordar essas classes com detalhes em alguns artigos. Nesse primeiro artigo iremos falar da classe Instant.

Instant 

Um instante é um ponto na linha do tempo. Essa classe deve ser usada eventos de timestamp (marcas de tempo) em uma aplicação, como por exemplo, saber em que exato momento do tempo um determinado evento ocorreu. Ela lembra muito o método System.currentTimeMillis(), só que sua precisão é de nanosegundos. Outras características relevantes dela são:
  • O instante 0 (Zero) é 01/01/1970 T00:00:00 (conhecido como Era Unix)
  • O instante mínimo, Instant.MIN, é simplesmente 1 bilhão de anos atrás
  • O instante máximo, Instant.MAX, é a data 31/12/1000000000 :)
  • O instante atual é obtido através do método: Instant.now()
  • Um dia em Java, tem exatamente 86400 segundos 

No código a seguir, podemos ver algumas formas de usar a classe Instant:


Podemos já de cara ver que os métodos plusSeconds e minusSeconds retornam um objeto do tipo Instant. Isso é o que garante a imutabilidade da classe, isso quer dizer que nenhum chamada de método irá causar efeitos no seu objeto, ao invés disso, uma nova instância é retornada com o valor modificado. A última linha prova que t1 não sofreu nenhum efeito com a chamada do método t1.plusSeconds(10), isso faz com que o objeto possa ser seguramente manipulado em ambientes concorrentes.

Duration

Como você fazia pra medir o tempo de execução de uma determinada operação, lembra?


Agora existe uma classe especializada em fazer esse tipo de operação: Duration. Uma Duration representa a quantidade de tempo decorrido entre dois instantes (Instant). Ela modela a quantidade de tempo em segundos ou em nanosegundos, porém ela possui métodos para calcular o tempo em milissegundos, minutos, horas e dias. Vejamos como ficaria a classe anterior usando Instant e Duration:

Pra finalizar, a classe Duration possui uma maneira de ser 'instanciada', isso pode ser feito através dos métodos of. Isso pode ser útil, por exemplo, caso você queira fazer uma comparação entre dois períodos. Digamos que eu queira comparar se um determinado algoritmo é 10 vezes mais rápido que outro. Podemos fazer isso da seguinte maneira:

Ainda há muito o que explorar no pacote java.time. Neste post vimos duas de suas classes, Instant e Duration, além de alguns exemplos de como usá-las para resolver problemas de marcação e medição de tempo. No próximo artigo iremos conhecer mais duas classes, LocalDate e Period. Então, até o próximo post!

PS: Me perdoem pelo infame trocadilho no título deste post. Obrigado :)

Um comentário: