Java Time

LocalDate

Java Time LocalDate

O LocalDate representa uma data no formato ISO (aaaa-MM-dd) sem hora. Podemos usá-lo para armazenar datas como aniversários e dias de pagamento.

Instanciação

Já aprendemos que instanciar refere-se a criar um novo objeto onde o meio mais tradicional é pelo uso de Construtores, porém as classes citadas acima possuem métodos estáticos de criação de objetos correspondentemente.

Uma instância da data atual pode ser criada a partir do relógio do sistema:

import java.time.LocalDate;

public class JavaTime {
    public static void main(String[] args) {
        
        LocalDate dataAtual = LocalDate.now();
        
        System.out.println(dataAtual);
        //Representação de um LocalDate: 2023-03-01
    }
}

Também é possível determinar os dígitos para dia, mês e ano em um LocalDate utilizando o método of (year, month, dayOfMonth).

LocalDate dataEspecifica1 = LocalDate.of(2023,1,12);

LocalDate dataEspecifica2 = LocalDate.of(2023, Month.JANUARY,12);
🔔 Atenção
Dois itens devem ser analisados no exemplo acima:
Primeiro: Java Time considera que meses começam com 1 (janeiro), 2 (fevereiro) e ...
Segundo: Existe um enum denominado Month com os valores dos meses pré-definidos

Agora imagina que você tenha uma String onde seu conteúdo representa uma data, onde você gostaria de converter para um LocalDate correspondente? Simples, veja o código abaixo:

// este conteúdo pode ser um argumento de seu programa via console
// ou toString() de algum componente visual
String stringData = "2023-01-17";

LocalDate dataConcreta = LocalDate.parse(stringData);

Até aqui já aprendemos variedades sobre Data utilizando Java Time, mas nós como bons brasileiros sabemos que o formato de uma data informada no sistemas desktops, web e aplicativos possuem um formato diferente. Então como converteríamos uma string de data vindo no formato dd/mm/aaaa? Este é um trabalho para a classe java.time.format.DateTimeFormatter

String stringDataBr = "17/01/2023";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");

LocalDate dataConcreta = LocalDate.parse(stringDataBr,formatter);
🚨 Cuidado
Tentar converter uma String em um JavaTime que não tenha uma compatibilidade de conversão (parse) gerá uma exceção semelhante a esta:java.time.format.DateTimeParseException: Text '17/01/23' could not be parsed

Manipulação

Depois de um objeto LocalDate criado na sua aplicação, você poderá, manipulá-lo resultando na criação de novos objetos com os valores resultantes de operações como: adicionar dia, subtrair mês e etc.

LocalDate aniversarioIzabelly = LocalDate.of(2023,5,4);
LocalDate aniversarioIzabelly = LocalDate.of(2023,5,4);

LocalDate dataQueTera15Anos = aniversarioIzabelly.plusYears(15);

System.out.println(dataQueTera15Anos);
🏆 Sucesso
Agora que já compreendeu grande parte dos recursos de um LocalDate, que tal explorar os demais métodos plusXX e minusYY?

Comparação

Outro aspecto extremamente relevante quando trabalhamos com data é realizar comparações entre duas datas com base no: ano, mes, dia, semana e etc.

LocalDate data1 = LocalDate.of(2023,3,4);
LocalDate data2 = LocalDate.of(2024,4,3);

//data2 está após a data 1? true
System.out.println(data2.isAfter(data1));

//data2 está antes que data 1? flase
System.out.println(data2.isBefore(data1));

//data2 é igual a data 1? false
System.out.println(data2.isEqual(data1));

Formatação

Assim como explanamos formatação de datas utilizando DateFormat e SimpleDateFormat, agora o Java Time disponibiliza recursos para formatações de data e hora nesta nova abordagem da linguagem.

Abaixo iremos explorar formatações considerando um formato pré-estabelecido e em seguida formatos com base na Local e (idioma) configurado em sua aplicação.

LocalDate data = LocalDate.of(2023,1,13);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");

System.out.println(data); //2023-01-13

//formatando a data criada acima
System.out.println(formatter.format(data)); //13/01/2023

Se você pretende desenvolver uma aplicação no qual é necessário considerar a região em que o usuário acessará o sistema para formatar campos data adequadamente, é possível realizar esta formatação com quatro formatos pré-definidos:

LocalDate data = LocalDate.of(2023,1,13);

String dataFormatada = data.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG));  //13 de janeiro de 2023
dataFormatada = data.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM));  // 13 de jan. de 2023
dataFormatada = data.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT));  // 13/01/2023
dataFormatada = data.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));  // sexta-feira, 13 de janeiro de 2023
🔔 Atenção
A formatação apresentada acima poderá ter um comportamento diferente considerando as configurações de região e idioma em sistema operacional.Para definir uma formatação mediante uma seleção de um idioma em sua aplicação, recomendo explorar um pouco mais sobre o uso de Locale

Considerando a imagem abaixo, vamos apresentar a mesma data 23/08/2021 nas respectivas formatações abaixo:


LocalDate data = LocalDate.of(2021,8,23);

Locale[] locales = {Locale.CANADA, Locale.US, new Locale("fi","FI"),Locale.UK};

for(Locale locale:locales){
    String dataFormatada = data.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(locale));
    System.out.println(dataFormatada);
}

// 2021-08-23
// 8/23/21
// 23.8.2021
// 23/08/2021

Dados específicos

Depois de aprendermos a instanciar, manipular e formatar datas utilizando os recursos do Java Time, chegou a hora de obter alguns dados isoladamente através de métodos específicos:

LocalDate data = LocalDate.of(2021,8,23);

System.out.println(data.getDayOfMonth());   // retorna o dia do mês -> 23
System.out.println(data.getYear());         // retorna o ano -> 2023
System.out.println(data.getMonth());        // retorna o elemento de enum java.time.Month -> AUGUST
System.out.println(data.getMonthValue());   // retorna o número do mês entre 1-12 -> 8