Wrong date calculation

Asked

Viewed 105 times

4

I have the following method:

TimeSpan dt = dataFinal.Subtract(dataInicial);

double anos = Math.Floor(dt.Days / 365.25);
double meses = Math.Floor(((dt.Days - anos * 365.25) / 30));

return string.Format("{0} Anos e {1} mês(es)", anos, meses);

It receives a date and calculates the time between the two dates. But if I pass for example:

DataIncial -> 11/03/1992
dataFinal -> 11/03/2015

he should return to me 23 anos e 0 mes(es), but it’s returning 22 anos e 12 mes(es).

How can I fix this?

  • 2

    I see nothing wrong, the two results are equal (23 years and 0 months equals 22 years and 12 months). I think it’s just a matter of formatting the output of the result.

  • Use the Totaldays property

2 answers

7


Alternatively you can use a library that knows how to handle this properly like the Noda Time of Jon Skeet (I wanted her to become an official of .NET). He has already set an example by doing this in that reply:

var start = new LocalDateTime(2014, 1, 1, 8, 30);
var end = new LocalDateTime(2014, 9, 16, 12, 0);
Period delay = new PeriodBuilder { 
        Months = 8, 
        Days = 10,
        Hours = 2,
        Minutes = 20
    }
    .Build();
Period difference = (Period.Between(start, end) - delay).Normalize();

I put in the Github for future reference.

Why is this alternative good? Because she thought of everything. The way the question is being asked is naive and disregards, for example, that months have a number of different days and leap years in the right way (even if it looks like it is). If you want a real, non-approximate solution, then do it the right way. In the current form several moments will give wrong results, although most can get it right. But it’s coincidence. As they say: even a stopped clock will mark the right time twice a day.

It is possible to write own code to deal with this but it is not the focus of the question and probably I would forget some point and the algorithm would not be reliable.

2

You can fix this with a variable check meses before printing.

if(meses == 12) {
  meses = 0;
  anos++;
}

return string.Format("{0} Anos e {1} mês(es)", anos, meses);
  • I was writing a reply just like yours. As already posted, I will leave only your.

Browser other questions tagged

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