Trabalhando com datas em Java - Parte I

Trabalhar com datas pode ser bastante desafiador porque não estamos acostumados a fazer certas destinções que em software são muito importantes.

Até ao Java 8, o programador Java tinha que utilizar as classes Date e Calendar para presentar datas e horas e fazer cálculos. Esta APi não era ideal e levava a muitos erros, principalmente por não distinguir entre os conceitos-chave necessários ao trabalhar com datas e horas.

A partir do Java 8 uma nova API - JSR-310 Date and Time API - foi introduzida para simplificar a manipulação e os cálculos com datas e tempos: java.time que substitui o uso da API antiga. As classes Date e Calendar ainda estão presentes no SDK, mas é recomendado não as utilizar.

Local e Regional

Sempre que trabalhamos com tempos, é importante informar se estamos utilizando um referencial local, ou um referencial regional. Em Java, simplesmente usamos classes diferentes. O referencial local utiliza sempre as classes com o prefixo Local. O referencial regional sempre utiliza as classes com o prefixo Zoned. Na realidade só existe uma classe no referencial regional chamada ZonedDateTime.

Conversão de Local para Regional

Se temos um valor regional ZonedDateTime de uma certa região e queremos obter o correspondente valor local, nessa região, basta tuilizarmos o método toLocalDateTime. Notar que isto só é válido se a região presente em ZonedDateTime é a mesma que a região local.

Se a região não é a mesma, primeiro transferimos a região para a região local com o método withZoneSameInstant e depois utilizamos toLocalDateTime. Para realizar esta operação precisamos conhecer o ZoneId da região local.

Por outro lado, se temos um valor LocalDateTime e queremos converter para um ZonedDateTime só podemos fazer isso para a região local, sabendo seu ZoneId e utilizando o método atZone de LocalDateTime. Isto irá criar um ZonedDateTime no mesmo momento que o LocalDateTime dado. Notar que isto só é válido se o ZoneId é região local.

ZoneId saoPaulo =  ZoneId.of("America/Sao_Paulo");
ZoneId tokyo =  ZoneId.of("Asia/Tokyo");

// Local to Zoned


LocalDateTime implicitlyInSaoPaulo = LocalDateTime.of(2024, 2, 14, 12, 45); // 2024-02-14 12h45
ZonedDateTime explicitltyInSaoPaulo = implicitlyInSaoPaulo.atZone(saoPaulo);  // 2024-02-14 12h45 GTM-3:00

// transferindo para toquio

ZonedDateTime explicitltyInTokyo = explicitltyInSaoPaulo.withZoneSameInstant(tokyo); // 2024-02-14 15h45 GTM+9:00

// Zoned to Local
LocalDateTime implicitlyInTokyo = explicitltyInTokyo.toLocalDateTime(); // 2024-02-15 00h45

Cálculos com datas e tempos

É comum precisarmos adicionar, ou subtrairmos, dias, meses ou anos de datas.

Para isso utilize o método plusYYY onde YYY é o sufixo relativo a qual unidade queremos modificar.

LocalDate natal = LocalDateTime.of(2024, 12, 25);

LocalDate anoNovo = date.plusDays(7);

É importante diferenciar entre incrementar o mês e adicionar 30 dias. Não vai dar o mesmo resultado, pois nem todos os meses têm 30 dias.

Se esperamos um cálculo que corresponde com "a cada dia 10 de cada mês", por exemplo, para uma conta a pagar, então adicionamos sempre 1 no mês. Desta forma o dia do mês se mantém igual

LocalDate primeiro = LocalDateTime.of(2024, 1, 10); // 2024-01-10

LocalDate segundo = primeiro.plusMonth(1); // 2024-02-10

LocalDate terceiro = primeiro.plusMonth(2); // 2024-03-10

Muito cuidado ao realizar cálculos com datas, à que escolher sempre corretamente qual valor incrementar.

Scroll to Top