Como receber um String do Scanner e converter em Date?

Pessoal, Bom dia!

Estou com esse problema…
Vi varios topicos em varias paginas, mas nenhum deles estão me ajudando.

preciso receber um date pelo scanner no formato string, converter ele em Date temporario, e em seguida alocar ele a um construtor.

segue o codigo:

ublic class Program121 {
public static void main(String[] args) {

	Scanner sc = new Scanner(System.in);
	System.out.println("Enter cliente data: ");
	System.out.println("Nome: ");
	String tempNome = sc.next();
	System.out.println("Email: ");
	String tempEmail = sc.next();
	System.out.println("data de nascimento: *dd/MM/aaaa* ");
	String tempData = sc.next();
	
	SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy");
	Date format = f.parse(tempData);
	Client121 pessoa = new Client121(tempNome, tempEmail, format);
	
	sc.close();

Fiz assim, porém não funcionou.

Agradeço de já seu tempo e atenção. :smiling_face_with_three_hearts:

Substitua sc.next() por sc.nextLine().
Outra coisa, o método parse( String ) lança uma exceção checada chamada ParseException.

try {
    SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy");
    Date format = f.parse(tempData);
    Client121 pessoa = new Client121(tempNome, tempEmail, format);
} catch ( ParseException exc ) {
    System.out.println( "data informada em formato errado!" );
}
1 curtida

Explica exatamente o por quê de não ter conseguido. É que eu testei aqui e funcionou normalmente.

A única coisa que eu fiz foi adicionar um throws no método main e ficou assim:

public static void main(String... args) throws ParseException {
1 curtida

Não funciona se colocar espaços no nome, por exemplo. Tem que ler a linha inteira, não somente um token do Scanner.

Outra coisa, throws no método main é só para testar, pois é uma PÉSSIMA decisão de implementação se for algo de verdade ao invés de um programa de brinquedo.

1 curtida

Verdade, eu só testei sem espaços.

Esses são os erros… Estranho kkk

Notei 2 coisas:

  1. Falta o import do ParseException
  2. Vc tá usando java.util.Date em algum lugar em que java.sql.Date é esperado.

EDIT:
Seu import está errado, vc tem que importar java.util.Date, não java.sql.Date.

1 curtida

Verdade.

era isso mesmo kkkkk

Muito obrigado!
Desculpem a falta de experiencia. Estudo sozinho e vivo enroscado em algumas coisas!

Obrigado pelo tempo de todos :smiling_face_with_three_hearts:

1 curtida

Pelo seu screenshot deu pra ver que você está usando Java 11, sendo assim, por que não usar a nova API de datas (java.time)? Date e SimpleDateFormat são API’s antigas (o próprio tutorial da Oracle chama de “API legada”), que possuem uma série de problemas e falhas de design que foram corrigidas na API nova.

O uso de Date em versões mais novas só se justifica se está lidando com código legado que ainda depende desta classe. Mas para código “novo”, não há impedimentos para que se use o java.time.

No seu caso, por exemplo, como você só tem dia, mês e ano, uma alternativa é usar java.time.LocalDate:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;

...
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/uuuu").withResolverStyle(ResolverStyle.STRICT);
LocalDate data = LocalDate.parse(tempData, fmt);

Usei o ResolverStyle.STRICT para que não aceite datas inválidas. Se não usar isso, serão aceitas datas como 31 de fevereiro (que é “ajustado” para dia 28 - ou 29 se o ano for bissexto). No modo STRICT esses ajustes não são feitos e as datas inválidas lançam exceção (DateTimeParseException).

Aliás, SimpleDateFormat por padrão aceita essas datas inválidas também (e faz uns ajustes bem bizarros, dependendo do caso). Se não quer aceitar datas inválidas, bastaria fazer f.setLenient(false) (caso decida continuar usando o SimpleDateFormat).

Mas se for usar o java.time, você teria que mudar a classe Client121 para usar LocalDate em vez de Date. Mas eu não usaria a API antiga, a menos que haja algum forte motivo (como compatibilidade com código legado, por exemplo).

E se ocorrer algum erro, o código acima lança um DateTimeParseException, mas como esta é uma exceção não-checada, você não é obrigado a capturá-la (como ocorre com ParseException). Claro que se quiser, pode fazer a validação:

try {
    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/uuuu").withResolverStyle(ResolverStyle.STRICT);
    LocalDate data = LocalDate.parse(tempData, fmt);
    // usar a data...
} catch (DateTimeParseException e) {
    System.out.println("Erro: " + e.getMessage());
}
2 curtidas

Cara. Muito obrigado pelo seu tempo dedicado. Vou seguir essa ideia aí :heart: