Difference of months between two dates, without considering the day of the month

Asked

Viewed 786 times

2

I am making an application for labor calculations. I need to receive two dates and know the amount of days/ months/ years.

Ex.: from 08/03/2017 to 07/03/2018 is to give 12 exact months, in my code is 11 months and 27 days. Someone knows how to fix this?

String dataEntrada, dataSaida;
dataEntrada = JOptionPane.showInputDialog(null, "Digite a data de entrada");
dataSaida = JOptionPane.showInputDialog(null, "Digite a data de saida");
String entrada[] = dataEntrada.split("/");
String saida[] = dataSaida.split("/");

LocalDate admissao = LocalDate.of(Integer.parseInt(entrada[2]), Integer.parseInt(entrada[1]),
        Integer.parseInt(entrada[0]));
LocalDate demissao = LocalDate.of(Integer.parseInt(saida[2]), Integer.parseInt(saida[1]),
        Integer.parseInt(saida[0]));
Period periodo = Period.between(admissao, demissao);
System.out
        .println(periodo.getYears() + " Anos " + periodo.getMonths() + " Meses " + periodo.getDays() + " Dias");

2 answers

1

What happens is that Period.between, in a way, "round down". For an exact month to be considered, the day of the month must be greater than or equal to the beginning.

For example, starting on 03/08/2017 and ending on 04/07/2017:

LocalDate admissao = LocalDate.of(2017, 3, 8);
LocalDate demissao = LocalDate.of(2017, 4, 7);
Period periodo = Period.between(admissao, demissao);
System.out.println(periodo.getYears() + " Anos " + periodo.getMonths() + " Meses " + periodo.getDays() + " Dias");

The exit will be:

0 years 0 Months 30 Days

As I started on March 8th, the API only considers a full month from April 8th. So if I change the dates to:

LocalDate admissao = LocalDate.of(2017, 3, 8);
LocalDate demissao = LocalDate.of(2017, 4, 8);

The exit will be:

0 years 1 Months 0 Days

In your example, the period starts on 03/08/2017 and ends on 03/07/2018, so the twelfth month was not completed (would only be completed from 03/08/2018).

This is the way the API does the calculations and there is no changing. If your rule for considering a whole month is different, some adaptations should be made.

A solution would be to add a day on the date of dismissal (as suggested in reply from @prmottajr), and then subtract this more than periodo.getDays().

I do not know exactly what your rule. It is from day 07/03/2018 that you consider 12 months? Or from 01/03/2018 should return 12 months?

If it is the second case (from 01/03/2018 already considers 12 months), you can simply ignore the day (transforming the LocalDate in a YearMonth, using the method from) and calculate the amount of months between them, using a java.time.temporal.ChronoUnit:

// YearMonth.from extrai o mês e o ano do LocalDate
YearMonth mesAnoAdmissao = YearMonth.from(admissao);
YearMonth mesAnoDemissao = YearMonth.from(demissao);
// quantidade de meses entre admissão e demissão
long meses = ChronoUnit.MONTHS.between(mesAnoAdmissao, mesAnoDemissao);

In case, how I’m using YearMonth and this class only has month and year (without any information about the day), the result will be the difference in months, without taking into account the day of the month (and therefore without the "problems" mentioned above).

Thereby, meses will be equal to 12. Then you can adjust for the amount of years if meses is greater than 12, for example:

long anos = meses / 12;
meses = meses - (anos * 12);

0

The method between nay includes the final date. Try doing:

LocalDate demissao = LocalDate.of(Integer.parseInt(saida[2]), Integer.parseInt(saida[1]),
                Integer.parseInt(saida[0])+1);
  • Sure, but the day count counts as one more day.

Browser other questions tagged

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