Gostaria de acrescentar alguns detalhes.
Por padrão, DateTimeFormatter
faz alguns ajustes que nem sempre são desejados. Por exemplo, teste com datas inválidas como 31/04/2023 (é inválida porque Abril tem 30 dias) ou 30/02/2023 (também inválida porque fevereiro não tem 30 dias):
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate dt1 = LocalDate.parse("31/04/2023", formatter);
System.out.println(dt1); // 2023-04-30
LocalDate dt2 = LocalDate.parse("30/02/2023", formatter);
System.out.println(dt2); // 2023-02-28
Repare que as datas são ajustadas respectivamente para 30 de abril e 28 de fevereiro. Esse é o comportamento default do DateTimeFormatter
, mas que nem sempre é desejável. Se a ideia é validar a data (ou seja, aceitar somente se a combinação dia-mês-ano for válida, em vez de fazer esses ajustes), então você precisa mudar o java.time.format.ResolverStyle
para STRICT
:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu")
.withResolverStyle(ResolverStyle.STRICT);
try {
// agora dá erro
LocalDate dt1 = LocalDate.parse("31/04/2023", formatter);
System.out.println(dt1);
} catch (DateTimeParseException e) {
System.out.println("Data inválida");
}
Também mudei o ano de yyyy
para uuuu
. De maneira bem resumida, u
funciona tanto para anos atuais quanto para datas A.C. (Antes de Cristo), aceitando anos negativos, enquanto y
precisa da Era (A.C. ou B.C.) para decidir se ano é Antes ou Depois de Cristo (no seu exemplo não vemos esses problemas porque a era é inferida e para datas atuais funciona normalmente). Talvez o uso de datas tão antigas não seja tão comum em muitas aplicações, mas de qualquer forma, o uso de u
em vez de y
é recomendado. Para mais detalhes, veja aqui.
E para formatar, você pode adicionar o dia da semana em outro formatador:
Scanner scan = new Scanner(System.in);
System.out.println("Entre com uma data: (dd/MM/yyyy) ");
String data = scan.nextLine();
DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/uuuu")
.withResolverStyle(ResolverStyle.STRICT);
LocalDate date = LocalDate.parse(data, parser);
System.out.println("Entre com a quantidade de dias: ");
int dias = Integer.parseInt(scan.nextLine());
LocalDate proximoDias = date.plusDays(dias);
DateTimeFormatter formatoSaida = DateTimeFormatter.ofPattern("dd/MM/uuuu (EEEE)", new Locale("pt", "BR"));
System.out.printf("\nDaqui a %d dias será dia %s\n", dias, formatoSaida.format(proximoDias));
Repare que no formato de saída eu usei o pattern EEEE
, que mostra o nome do dia da semana. E usando um java.util.Locale
, setei o idioma para pt-BR
(português do Brasil), assim ele mostra o dia em português (ex: “Terça-feira”, “Sábado”, etc). Da forma que vc fez, ele mostra o nome do enum
(“TUESDAY”, “SATURDAY”, etc). Eu entendo que mostrar no idioma correto torna a saída mais user-friendly, além de ser mais configurável (se quiser mudar, basta trocar o Locale
).
Outro detalhe é que, como o Scanner
está usando o System.in
, então você não deveria fechá-lo.
E note também que troquei para usar scan.nextLine()
, pois para ler entradas do teclado, misturar next
com nextInt
costuma dar problemas em muitos casos. Entenda melhor lendo aqui.