Input de Datas em backend

Qual seria o recomendo para input de “data-aniversario”, numa requisição POST numa aplicação backend?

Por exemplo: Tenho uma classe Pessoa, que tem atributo “DataAniversario”. Esse atributo deve ser instant ou string? Segundo minha lógica, o DTO da classe Pessoa, deve ser String, para depois formatar e guardar na classe Pessoa como Instant. Ou pode ser direto string no banco de dadoa mesmo?

No banco você pode salvar como datetime ou timestamp, nas suas classes de negócio manipula como data, localdate, localdatetime, instant e afins.

Para expor o dado para fora você formata se necessário e devolve como string.

1 curtida

Se for apenas dia, mês e ano, use java.time.LocalDate. E veja se o driver do banco já suporta os tipos do java.time (procure na documentação do banco, costuma ter uma lista dos tipos). Por exemplo, alguns bancos mapeiam LocalDate para coluna do tipo DATE, aí não precisa converter para String, basta passar a data direto.

Instant não é uma boa opção porque ela representa um timestamp, que corresponde a uma data e hora diferente em cada fuso horário. Mas para uma data de nascimento simples, apenas dia, mês e ano parece ser suficiente, então LocalDate é uma opção melhor.

2 curtidas

Quando usar INSTANT então? Por exemplo: Informar a data que a conta foi criada, a data de nascimento, isso pode se LocalDateTime ou conta criada poderá ser Instant?

Isso seria minha lógica! Deixar DTO como string e depois formatar para a entidade main

Se no banco a coluna é do tipo DATE (ou qualquer outro tipo de data), então vc usa o respectivo tipo no Java (LocalDate, por exemplo). Vc só formata na hora de mostrar para o usuário (ou para imprimir no log, gravar em arquivo, transmitir o dado para outro serviço, etc).


Depende. Se vc quer o instante exato em que algo aconteceu, independente do fuso horário, Instant é mais adequado. Se vc quer a data/hora específica de um local, sem informação de fuso horário, LocalDate ou LocalDateTime é o mais indicado.

Por exemplo, se eu tiver a data de 7 de agosto de 2023, às 8 da manhã:

LocalDateTime dt = LocalDateTime.of(2023, 8, 7, 8, 0);

Esta data corresponde a qual instante? Não dá pra saber, porque LocalDateTime não tem informação sobre o fuso horário, e em cada parte do mundo esta data/hora ocorreu em um instante diferente. No Japão, esta data e hora ocorreram 12 horas antes do Horário de Brasília (quando em São Paulo era 07/08/2023 às 8 da manhã, em Tóquio já era 8 da noite). Veja:

// 7 de agosto de 2023, às 8 da manhã (sem fuso horário)
LocalDateTime dt = LocalDateTime.of(2023, 8, 7, 8, 0);

// esta data/hora em São Paulo
ZonedDateTime sp = dt.atZone(ZoneId.of("America/Sao_Paulo"));
// esta data/hora em Tóquio
ZonedDateTime tk = dt.atZone(ZoneId.of("Asia/Tokyo"));

System.out.println(sp); // 2023-08-07T08:00-03:00[America/Sao_Paulo]
System.out.println(tk); // 2023-08-07T08:00+09:00[Asia/Tokyo]

// veja que os instantes não são os mesmos
System.out.println(sp.toInstant()); // 2023-08-07T11:00:00Z
System.out.println(tk.toInstant()); // 2023-08-06T23:00:00Z

// diferença entre as datas (sp está 12 horas atrás de tk)
System.out.println(ChronoUnit.HOURS.between(sp, tk)); // -12

// quando era 8 da manhã em SP, já era 8 da noite em Tóquio
System.out.println(sp.withZoneSameInstant(ZoneId.of("Asia/Tokyo")));
// 2023-08-07T20:00+09:00[Asia/Tokyo]

Ou seja, se vc só quer a data (dia, mês e ano), sem se importar com o fuso horário, use LocalDate - ou se quiser também o horário, LocalDateTime. Se quer o instante exato em que algo ocorreu, independente do fuso horário, Instant é melhor.

1 curtida