Construtor que recebe valores correspondentes a uma Data

Bom dia pessoal. tudo bem?

Estou com duvidas com esse exercicio…

Escreva um construtor para a classe Data que receba os valores correspondentes ao dia, mês e ano, e inicialize os campos
da classe, verificando antes se a data é válida.

Criei as variaveis, criei o construtor, referenciei as variaveis ao construtor porem a partir dai nao sei o que fazer. Podem me ajudar?

Está verificando se a data é válida?
Posta se código.

Bom dia amigo. Essa é a parte que eu nao sei como fazer kkkk.

eu fiz 2 classes, uma para data e construtor e outra pra rodar o programa.

DATA:

package constructor;

public class Data {
   private Integer dia;
   private Integer mes;
   private Integer ano;
   
   public Data() {
	   
   }
   
   public Data(int dia, int mes, int ano) {
	   this.dia = dia;
	   this.mes = mes;
	   this.ano = ano;
	   
   }

public int getDia() {
	return dia;
}

public void setDia(int dia) {
	this.dia = dia;
}

public int getMes() {
	return mes;
}

public void setMes(int mes) {
	this.mes = mes;
}

public int getAno() {
	return ano;
}

public void setAno(int ano) {
	this.ano = ano;

===============
PROGRAMA:

package Program;

import java.util.Scanner;

import constructor.Data;



public class DataTeste {
	
	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		System.out.println("Digite a data: ");
		System.out.println("dia: ");
		int diasc = sc.nextInt();
		
		System.out.println("mes: ");
		int messc = sc.nextInt();
		
		System.out.println("Ano: ");
		int anosc = sc.nextInt();
		
		Data d = new Data(diasc, messc, anosc);
		
		
		sc.close();
	}

meu conhecimento ainda é muito primitivo, desculpe se algo estiver errado :slight_smile:

Para validar a data, você tem que ver se os valores são válidos (mês entre 1 e 12, dia entre 1 e o valor máximo de dias daquele mês, etc).

Para o ano não está claro se pode aceitar qualquer coisa, ou se só aceita valores positivos, etc. Vamos assumir que o ano só pode ser maior ou igual a zero (mas se não for o caso, basta mudar conforme o critério desejado):

public class Data {
    private int dia, mes, ano;
    public Data(int dia, int mes, int ano) {
        validar(dia, mes, ano);
        this.dia = dia;
        this.mes = mes;
        this.ano = ano;
    }

    private void validar(int dia, int mes, int ano) {
        if (ano < 0) { // não pode anos negativos
            throw new IllegalArgumentException("Ano deve ser positivo");
        }
        if (mes < 1 || mes > 12) {
            throw new IllegalArgumentException("Mês inválido: " + mes);
        }
        // verifica o último dia do mês (pois um mês pode ter 28, 29, 30 ou 31 dias)
        int ultimoDia;
        switch (mes) {
            // meses com 30 dias
            case 4:
            case 6:
            case 9:
            case 11:
                ultimoDia = 30;
                break;
            case 2: // fevereiro
                if ((ano % 4 == 0) && (ano % 100 != 0 || ano % 400 == 0)) { // se é ano bissexto
                    ultimoDia = 29;
                } else {
                    ultimoDia = 28;
                }
                break;
            default: // demais meses
                ultimoDia = 31;
        }
        if (dia < 1 || dia > ultimoDia) {
            throw new IllegalArgumentException("Dia deve estar entre 1 e " + ultimoDia);
        }
    }
}

Mudei o tipo dos campos de Integer para int, pois não parece haver motivo para usar os wrappers (leia aqui para entender melhor).

Também tirei o construtor default (o que não recebe parâmetros), pois não parece ter sentido criar uma data sem os valores do dia, mês e ano - se fizer new Data(), os campos não terão valores válidos (se eles forem int, o valor deles será zero, e se forem Integer, serão null), então para que ter esse construtor? Eu entendo que uma data precisa obrigatoriamente receber os valores do dia, mês e ano, então deixe apenas o construtor que recebe os dados.

Na validação eu vejo os valores do ano e mês, e caso sejam inválidos, lanço uma exceção. Fiz assim porque não acho que faz sentido criar uma data inválida: se fizer algo como new Data(35, 91, 2010), faz sentido criar esta data? Eu acho que não, pois não existe dia 35 do mês 91, então lanço a exceção para que a data não seja nem sequer criada.

Para validar o dia eu vejo se está entre 1 e o último dia do mês (e este varia conforme o mês, e até mesmo conforme o ano, já que em anos bissextos fevereiro tem 29 dias). Se estiver fora deste intervalo, também lanço uma exceção.

E eu tiraria os setters e deixaria apenas os getters, pois uma vez criada uma data, faz sentido mudar os valores do dia, mês ou ano? Eu entendo que se mudar algum desses valores, passa a ser outra data, então não teria motivo para ter setters. Mas como é um exercício e este ponto não está claro, pode ser que “tanto faz”. Mas se for para manter os setters, então você teria que chamar o método validar dentro deles também, algo do tipo:

public void setDia(int dia) {
    validar(dia, this.mes, this.ano); // valida o novo dia antes de mudar
    this.dia = dia;
}

public void setMes(int mes) {
    validar(this.dia, mes, this.ano); // valida o novo mês antes de mudar
    this.mes = mes;
}

public void setAno(int ano) {
    validar(this.dia, this.mes, ano); // valida o novo ano antes de mudar
    this.ano = ano;
}

Claro que isso só vale se for um exercício. Para código em sistemas reais, use o que já tem pronto. No caso, você poderia usar java.time.LocalDate (em vez de criar um classe Data própria, pois na grande maioria das vezes não há motivo para reinventar a roda, ainda mais com datas, que pode não parecer, mas é mais complicado do que parece).

1 curtida

Quando ler entrada de dados do TECLADO utilize somente o método nextLine(), você está usando o nextInt().
Há bastante material explicando isso.

Não se deve fechar o System.in e você está chamando o close() de um Scanner que lê o System.in.

1 curtida

Cara muito obrigado mesmo! Fiquei meio confuso com relação a validação de fevereiro. Porem foi de imensa utilidade sua explicação! obrigado pelo tempo dedicado para responder minha duvida :blush:

Hugo, desculpe mas surgiu outra duvida.

Como eu usaria esta classe no programa geral?

Use da forma que já está usando. Talvez a única coisa a mais seria capturar a exceção no caso de data inválida:

try {
    int dia, mes, ano;
    // ler dia, mês e ano com Scanner...

    Data d = new Data(dia, mes, ano);
    // usar a data...
} catch (IllegalArgumentException e) {
    // data inválida 
    System.out.println(e.getMessage());
}
1 curtida