[RESOLVIDO] Verificação de data buscando dados de outro método

8 respostas
java
CelsoRodrigo

Boa tarde,

Iniciei meus estudos e estou com uma grande dúvida. Apesar das leituras que fiz de validação de data em Java, ainda não consegui resolver meu problema.

Estou com um exercício onde há um método que lê um arquivo com extensão .csv e dentro dele há uma coluna com data.

public static void LerArquivos() {

String csvArquivo = "arquivo.csv";

	BufferedReader conteudoCSV = null;
	String linha = "";
	String csvSeparadorCampo = ";";
	boolean primeiraLinha = true;

	try {

		conteudoCSV = new BufferedReader(new FileReader(csvArquivo));

		while ((linha = conteudoCSV.readLine()) != null) {

			if (primeiraLinha) {
				primeiraLinha = false;
				continue;
			}

			String[] dados = linha.split(csvSeparadorCampo);

			System.out.println(" " + dados[0] + "  " + dados[1] + "  " + dados[2] + "  " + dados[3] + "  "
					+ dados[4] + "  " + dados[5] + "  " + dados[6] + "  " + dados[7] + "  " + dados[8] + "  "
					+ dados[9] + "  " + dados[10] + "  " + dados[11]);
			
			
					
		}

	} catch (FileNotFoundException e) {

		System.out.println("Arquivo não encontrado: \n" + e.getMessage());

	} catch (ArrayIndexOutOfBoundsException e) {

		System.out.println("IndexOutOfBounds: \n" + e.getMessage());

	} catch (IOException e) {

		System.out.println("IO Erro: \n" + e.getMessage());

	} finally {

		if (conteudoCSV != null) {

			try {

				conteudoCSV.close();

			} catch (IOException e) {

				System.out.println("IO Erro: \n" + e.getMessage());

			}

		}

	}

}

Dentro dos dados retornados, tenho dados[1] onde traz a data dentro do arquivo. Gostaria de validar o formato dela para “dd/MM/yyyy”, pois o usuário pode preencher a data com “28-05-2019”. Cheguei a criar um outro método, mas ainda assim não me retorna a data como inválida.

public boolean validaData(String dateToValidate) throws ParseException {

if ((dateToValidate == null) || (dateToValidate.equals(""))) {
		throw new NullPointerException("A data passada é nula ou vazia");
	}
	
	String[] dados = null;
	dateToValidate = extracted(dados)[1];
		
	SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
	sdf.setLenient(false);
	
	try {
		
		Date data = sdf.parse(dateToValidate);
		System.out.println(sdf.format(data));
		
	} catch (ParseException e) {
		
		System.out.println("Formato de data inválida: \n" + e.getMessage());
					
	}
	
	return true;

}

private static String[] extracted(String[] dados) {
	return dados;
}

Se puderem me auxiliar, fico grato!

8 Respostas

adriano_si

Veja o exemplo que fiz pra tentar explicar a você

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Data {

    private SimpleDateFormat sdf;

    public static void main(String[] args) {
        Data dt = new Data();

        String[] datas = new String[] {"29-05-2019","05-04-2010", "10-11-1985", "08-07-2000"};

        for (String data : datas) {
            System.out.println("Testando as entradas...");
            System.out.println("Testando a data " + data + ": " + dt.dateToString(dt.stringToDate(data, "dd-MM-yyyy")));
        }
    }

    public Date stringToDate(String data, String format) {
        sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(data);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }

    public String dateToString(Date data) {
        sdf = new SimpleDateFormat("dd/MM/yyyy");
        return sdf.format(data);
    }
}

Perceba que o que você quer fazer tem 2 passos distintos:

1 - Passar uma String que está em um formato específico para uma data
Nesse processo você terá que ter bastante cuidado pois um detalhe importante que deve ser ressaltado é que você tem que garantir que o formato da String de data do seu CSV será sempre o mesmo.

Isso é importante porque quando você faz um parse de String pra Date você necessita informar ao seu SimpleDateFormat qual o formato daquela String, ou seja, onde está o dia, onde está o mês e onde está o ano naquela String que o SimpleDate está recebendo. É exatamente aqui que está o problema no seu programa acima, você está fazendo o parse da sua data já para o formato dd/MM/yyyy.

2 - Formatar sua data para uma String humana
Se você printar uma data em Java verá que na verdade o que você tem é um long com os milisegundos da data de 01/01/1970 se não me engano até o momento atual da data que você tem, logo isso seria extremamente ilegível para um humano, então o SimpleDateFormat precisa de um formato para que o método format consiga apresentar pra você um valor que lhe interessa. Logo, ao passar pra ele dd/MM/yyyy você está dizendo que quer que ele monte pra você a data nesse formato.

É muito comum ficar meio perdido com isso ao começar a aprender Java, por conta desses detalhes, mas com o tempo você realmente acostuma.

Se ficar com alguma dúvida ou tiver algum problema fique a vontade para perguntar. :wink:

CelsoRodrigo

Adriano,

O programa sempre trabalhará com a data no formato “dd/MM/yyyy” e o usuário pode vir a preencher no arquivo o formato “dd-MM-yyyy”.

Neste caso, eu preciso primeiro passar a string que recebi no arquivo para o formato Date, correto? Depois preciso utilizar o SimpleDateFormat para passar esse formato Date para comparar com o formato que eu preciso, correto?

adriano_si

Isso. Exatamente isso, quando você faz o parse da String pro Date, precisa dizer ao sdf qual o formato que está sua String. Essa é a grande complicação, porque pelo jeito tem mais uma coisa que você tem que fazer antes de fazer o parse pelo que entendi da sua declaração abaixo

ou seja, então pode ser que no seu CSV você tenha datas no formato dd/MM/yyyy ou dd-MM-yyyy é isso? O usuário ainda pode enviar datas em outros formatos como MM-dd-yyyy ou yyyy-MM-dd ?

CelsoRodrigo

Sim, eu recebo o arquivo e o leio em um método. Depois em outro método, estou validando se o formato de data é o esperado - “dd/MM/yyyy”

Sim, as datas podem vir informadas nos formatos dd/MM/yyyy ou dd-MM-yyyy, aí que entra a validação da data. Outros formatos de data não são informados no arquivo.

A minha maior dificuldade está em compreender a extração também, que estou fazendo no método de validação da data, acredito que esteja correto, rsrs.

adriano_si

Então no momento do parse da String para data você deve apenas validar se a data é no formato dd-MM-yyyy, afinal se ela veio no formato dd/MM/yyyy então ela já está correta certo?

Você pode usar expressão regular pra validar toda a sua data, mas se tem certeza que seu arquivo sempre trará uma data válida, basta você verificar se a String da data contém o caractere “-” e então fazer o parse.

CelsoRodrigo

Valeu pela ajuda Adriano, tentarei resolver aqui hahahahah

CelsoRodrigo

Opa Adriano, consegui aqui deixando o código no seguinte formato. Valeu pela ajuda!!!

public static void validaData() {

Date dt = new Date();
	
	String[] datas = new String[] {"29-05-2019","05-04-2010", "10-11-1985", "08-07-2000"};
	
	for(String dateTovalidate : datas) {
		
		System.out.println("Testando as datas " + dateTovalidate);
	
		try {
			
			dt = stringToDate(dateTovalidate, "dd/MM/yyyy");
			System.out.println("DATA VALIDADA OK: " + dateToString(dt));
			
			} catch (ParseException e) {
				
				System.err.println("DATA INVÁLIDA: " + e.getMessage());
				
			}
		
	}
	
	
	
}

private static String[] extracted(String[] dados) {
	return dados;
}

public static Date stringToDate(String dateTovalidate, String format) throws ParseException {
	
	Date dataRetorno = null;
	
	if ((dateTovalidate == null ) || (dateTovalidate.equals(""))) {
		throw new NullPointerException("A data não pode ser nula ou vazia!");
		
	}
	
	SimpleDateFormat sdf = new SimpleDateFormat(format);
	sdf.setLenient(false);
	dataRetorno = sdf.parse(dateTovalidate);
	
	return dataRetorno;
}

public static String dateToString(Date dateToValidate) {
	
	SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
	sdf.setLenient(false);
	
	return sdf.format(dateToValidate);
	
}
adriano_si

Boaaaaaaa man… Bem lembrado de setar o lenient para false… Faz bastante sentido no seu cenário :wink:

Criado 27 de junho de 2019
Ultima resposta 2 de jul. de 2019
Respostas 8
Participantes 2