Get number of months between two dates

Have been trying for a very long time to calculate the age of breeding animals exactly in Years - Months - days.
I realize that months have variable lengths and two animals with the same age in days can have different months and days but my customers insist on using months.
I changed to weeks and days for animals under 1 year and it was perfectly accurate, but they hated it. However the customer is always right so I’m pressing on.
I’ve tried all the forum examples here over the years and I’ll tell you at one stage or another every one of them produced an inaccurate result -
Many of the posters give examples that need a little “tweaking” but that tweaking never ends because there is always fringe dates that simply don’t fit into the formula.
It’s hard to test the error as it involves subtracting the date of birth from the computer date. So out of the blue on a particular day some animals ages are inaccurate, the next day different ones.
Frequent fails on particular dates in leap years produce an extra month in the result. If I adjust the code they fail on regular years.

You could try something like

Var d As DateTime = DateTime.Now
Var birthdate As New DateTime(2000, 2, 28, 9, 30, 0, 0, TimeZone.Current)
Var interval As DateInterval = d - birthdate
Var months As Double = interval.Years * 12 + interval.Months + ((30 / (30 - interval.Days)) / 10)

hmm, maybe use the average days of all month and you get a decimal value for month.
as example 60 days / 30 days per month average = 2 Month
(i don’t know the average days of a month)

Var d1 As New DateTime(2018, 8, 1, TimeZone.Current)
Var d2 As New DateTime(2015, 3, 1, TimeZone.Current)
// Subtract seconds and convert seconds to days
Var days As Double = (d1.SecondsFrom1970 - d2.SecondsFrom1970) / (24 * 60 * 60)

What a human calls ‘2months’ is always open to interpretation.

1 Jan to 1 May is a 4 month gap

‘sometime in January’ to ‘sometime in May’ could be 4.2 months.
It could be 5 ‘months in which something happened’

If you look at the calendar day and look for a matching calendar day, you will have trouble checking during February

But given an average ‘length of month’ and applying that to ‘difference in days’ will ALWAYS turn up edge cases where the user disagrees with your figure if you suggest the answer is hard and fast. Especially if you just take the integer part of the answer.

Perhaps if you take the number of days, divide by an average day count, and then round up or down to the nearest integer, you could say ‘about 3 months’ and cover your back…?

What about this kind of answer:
42 Months (3 years, 5 Months and 12 days)

There is the number of months and the exact age.

Yes, there is something I do not understand in your question.
Jan 1st to March 31 = 3 Months. *
March 1st to May 31st = 3 Months. *

  • Yes, the number of days is different, but you say that in parenthesis.
    And you have to take into account leap years; fortunately, for animals the 100 and 400 cases does not apply. (BTW: I suddenly have a doubt; if in nature, I am not sure, in farms I think it is true).

I would compute the number of months from the birth date (say July 25th) to this month, for the number of months…

I never used DateInterval, so I will use TotalSeconds:

today.TotalSeconds - BirthDay.TotalSeconds

and convert the result n a Age Date, then present both as suggested above.

Of course, I may be wrong on a Sunday morning.

Sorry to cause confusion. They want the age of the animal displayed in Years, months and days.
For example an animal born on 18th July 2020 will display the age today (3rd May) as “9 months 2 weeks 1 day”.
They think in Calendar months so 18th July 2020 to 18th April 2021 is 9 months. The remaining 15 days is simply divided by 7 to get weeks and days.

I know this is not an accurate way to compare the age of two animals as two animals born on different dates can display the same age even when they are different days old. Much worse in leap years.

this calculates years 0 month 9 days 14.
you need xojo 2019r2 or later

Var d1 As DateTime = New DateTime(2020,7,18)
Var d2 As DateTime = DateTime.Now
Var i As DateInterval = d2 - d1
System.DebugLog "years " + i.Years.ToString + " month " +i.Months.ToString + " days " +i.Days.ToString

1 Like

Thanks I will have a look at it. I may need to look at old solutions again in newer versions of Xojo.

Forum for Xojo Programming Language and IDE. Copyright © 2021 Xojo, Inc.