# [Lazarus] DateDif function needed

Michael Van Canneyt michael at freepascal.org
Mon Nov 11 17:25:21 CET 2013

```
On Mon, 11 Nov 2013, John Landmesser wrote:

> That's what i realized until now::
>
> Quote of lhelp:
> "MonthsBetween returns the number of whole months between ANow and AThen.
> This number is an approximation, based on an average number of days of
> 30.4375
>
> per month (average over 4 years). This means the fractional part of a month
> is dropped."

>
> MonthsBetween('01.01.2000', '01.03.2000') = 1(!!)
>
> This wrong(!!) result is according to the explanation in the lhelp file, but
> this function is useless if you have leapyears in your period.

The result is correct.

The number of elapsed DAYS between these 2 dates is 60.
If the average number of days per month is assumed to be 30.4375,
then 2 full months would be 60.875 days.

That means that 60 days DOES NOT span 2 full months of 30.4375 days:
it falls 0.875 days short for that.

Hence, the *intended* result is 1.

Check the output of:

uses sysutils,dateutils;

begin
Writeln('Days ',DaysBetween(EncodeDate(2000,1,1),EncodeDate(2000,3,1)));
Writeln('Months : ',MonthsBetween(EncodeDate(2000,1,1),EncodeDate(2000,3,1)));
Writeln('Days ',DaysBetween(EncodeDate(2000,1,1),EncodeDate(2000,3,2)));
Writeln('Months : ',MonthsBetween(EncodeDate(2000,1,1),EncodeDate(2000,3,2)));
end.

it is

Days 60
Months : 1
Days 61
Months : 2

which, given the definition, is correct.

> Fazit:
>
> You can't write a DateDif function with the functions in DateUtils.pas ?!!

You can, but if you want EXACT results in the style of Y years, M months, D days,
you cannot calculate that with the functions you are using. You can use daysbetween
to calculate the number of days, this is an exact number. Calculating the number of
years and months can then be done exact, but is not trivial.

As it states in the documentation the above functions are an approximation based
on the above assumption on the average number of days in a month.

One can discuss whether such 'approximate' functions are useful, but that is another
discussion entirely. These functions are there for Delphi compatibility.

Given their definition they are correct.

So please stop saying that they are wrong.
You just don't understand their intended use correctly.

Michael.

```