Calculation of Age using Period

Asked

Viewed 86 times

0

I have this code below in Java that does not compile and I can not find the error. I have already made the targeted modifications and the number of errors has passed to only 1.

The method calculoIdade and validarData returns now the type Period, but when executing still presents type error in the method validarData.

import java.time.*;
import java.util.*;

public class Data {

  private int dia, mes, ano;
  String data;

  public void validarData() {

    if (dia > 0 && dia < 32 && mes > 0 && mes < 13 && ano > 0
        && ((mes == 1 || mes == 3 || mes == 5 || mes == 7 || mes == 8 || mes == 10 || mes == 12)
            || ((mes == 4 || mes == 6 || mes == 9 || mes == 11) && dia <= 30)
            || (mes == 2 && (dia <= 29 && ano % 4 == 0 && (ano % 100 != 0 || ano % 400 == 0)) || dia <= 28))) {
      data = "Data válida";
    } else {
      data = "Data inválida";
    }
  }

  public Double calculoIdade(int dia,int mes, int ano) {
        if (validarData()) {
            LocalDate data = LocalDate.of(dia, mes, ano);
            LocalDate now = LocalDate.now();
            if (ano <= 2020) {
                Period diff = Period.between(data, now);
            }
        } else {
            System.out.println("Quantidade de dias excede o total de dias do mês");
        }
    }

  public void main(String[] args) {
    Scanner leia = new Scanner(System.in);
    System.out.print("Digite o dia: ");
    dia = leia.nextInt();
    System.out.print("Digite o mês: ");
    mes = leia.nextInt();
    System.out.print("Digite o ano: ");
    ano = leia.nextInt();
    System.out.println("Idade: %d anos, %d meses e %d dias", diff.getYears(), diff.getMonths(), diff.getDays());
    System.out.println(+dia + "/" + mes + "/" + ano + " " + data);
  }

}

After the fixes, the code looked like this:

import java.time.*;
import java.util.*;

public class Main {

  private static int dia, mes, ano;
  private String  data;
  private Period diff;
  
  public Period validarData() {

    if (dia > 0 && dia < 32 && mes > 0 && mes < 13 && ano > 0
        && ((mes == 1 || mes == 3 || mes == 5 || mes == 7 || mes == 8 || mes == 10 || mes == 12)
            || ((mes == 4 || mes == 6 || mes == 9 || mes == 11) && dia <= 30)
            || (mes == 2 && (dia <= 29 && ano % 4 == 0 && (ano % 100 != 0 || ano % 400 == 0)) || dia <= 28))) {
      data = "Data válida";
    } else {
      data = "Data inválida";
    }
  }

  public Period calculoIdade(int dia,int mes, int ano) {
        if (validarData()) {
            LocalDate l = LocalDate.of(dia, mes, ano);
            LocalDate now = LocalDate.now();
            if (ano <= 2020) {
                Period diff = Period.between(l, now);
            }
        } else {
            System.out.println("Quantidade de dias excede o total de dias do mês");
        }
    }

  public void main(String[] args) {
    Scanner leia = new Scanner(System.in);
    System.out.print("Digite o dia: ");
    dia = leia.nextInt();
    System.out.print("Digite o mês: ");
    mes = leia.nextInt();
    System.out.print("Digite o ano: ");
    ano = leia.nextInt();
    System.out.println("Idade: " + diff.getYears() + " anos, " + diff.getMonths() + " meses, "
                        + diff.getDays() + " dias");
    System.out.println(+dia + "/" + mes + "/" + ano + " " + data);
  }

}

This resulted in only 1 error, as below:

Main.java:24: error: incompatible types: Period cannot be converted 
to boolean
        if (validarData()) {
                       ^
1 error

What can I do?

1 answer

2


The problem is you did if (validarData()), and the condition of if must be a boolean. But you stated that the method validarData returns a Period, that is not a boolean.

Another detail is that the method validarData is not returning anything. If you declare that it returns something, at some point it must have a return to return the value.

In addition, the variable diff who is in the main is not the same as inside calculoIdade. Variables created within a method are local to the method and are not visible at other points in the program. And after you read the values of the day, month and year, missed calling the method to calculate the age.

Another detail is that LocalDate.of receives the values of the year, month and day in that order (you were passing in the wrong order).

Anyway, one way (not yet ideal, in my opinion - I left an alternative at the end) to solve these problems would be:

static boolean validarData(int dia, int mes, int ano) {
    // em vez de fazer um if gigante, quebre em várias condições
    if (mes < 1 || mes > 12) { // verifica mês inválido
        return false;
    }

    // se chegou aqui, é porque o mês é válido, então agora verifica o dia
    int qtdDias;
    if (mes == 2) {
        if (ano % 4 == 0 && ((ano % 100) != 0 || (ano % 400) == 0)) {
            qtdDias = 29;
        } else {
            qtdDias = 28;
        }
    } else if (mes == 4 || mes == 6 || mes == 9 || mes == 11) {
        qtdDias = 30;
    } else {
        qtdDias = 31;
    }
    return 1 <= dia && dia <= qtdDias;
}

static Period calculoIdade(int dia, int mes, int ano) {
    if (validarData(dia, mes, ano)) {
        if (ano <= 2020) {
            return Period.between(LocalDate.of(ano, mes, dia), LocalDate.now());
        }
    } else {
        // mudei a mensagem porque há mais de um motivo para ser inválida (mês negativo, por exemplo), então deixei a mensagem genérica
        System.out.println("Data inválida");
    }
    // se a data for inválida ou o ano for maior que 2020, retorna null
    return null;
}

public static void main(String[] args) {
    Scanner leia = new Scanner(System.in);
    System.out.print("Digite o dia: ");
    int dia = leia.nextInt();
    System.out.print("Digite o mês: ");
    int mes = leia.nextInt();
    System.out.print("Digite o ano: ");
    int ano = leia.nextInt();

    Period idade = calculoIdade(dia, mes, ano);
    if (idade != null) { // se não for null, é porque foi calculado
        System.out.printf("Idade: %d anos, %d meses e %d dias\n", idade.getYears(), idade.getMonths(), idade.getDays());
        System.out.printf("%02d/%02d/%d\n", dia, mes, ano); // %02d garante que valores como "2" sejam mostrados como "02"
    }
}

But it doesn’t really need any of that. The class itself LocalDate already checks if the date is valid, making an exception if it is not. Then just use what you already have ready, adding only the special case that checks whether the year is not greater than 2020 (although I think it best to simply check whether the date is in the future, instead of setting a year). To format the date, also have things ready, do not need to reinvent the wheel:

public static void main(String[] args) {
    Scanner leia = new Scanner(System.in);
    System.out.print("Digite o dia: ");
    int dia = leia.nextInt();
    System.out.print("Digite o mês: ");
    int mes = leia.nextInt();
    System.out.print("Digite o ano: ");
    int ano = leia.nextInt();

    try {
        LocalDate dataNasc = LocalDate.of(ano, mes, dia);
        LocalDate hoje = LocalDate.now();
        if (dataNasc.isAfter(hoje)) {
            System.out.println("Data de nascimento no futuro, não é possível calcular idade");
        } else {
            Period idade = Period.between(dataNasc, hoje);
            System.out.printf("Idade: %d anos, %d meses e %d dias\n", idade.getYears(), idade.getMonths(), idade.getDays());
            System.out.printf(DateTimeFormatter.ofPattern("dd/MM/uuuu").format(dataNasc));
        }
    } catch (DateTimeException e) { // se a data for inválida, LocalDate.of lança esta exceção
        System.out.println("Data inválida: " + e.getMessage());
    }
}
  • Dear @hkotsubo, thank you very much, now it’s worked.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.