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).