Solved

# of months between 2 dates

Posted on 2000-03-21
7
440 Views
Last Modified: 2010-04-04
How can I get the number of months between 2 dates?
For example: 01-jan-2000 and 02-feb-2000. I can have the # of days (Date2 - Date1). I can even "get" the # of months dividing it by 30, but it's not an EXACT calculation...
Any idea?
0
Comment
Question by:binho
  • 3
  • 2
  • 2
7 Comments
 
LVL 4

Expert Comment

by:jeurk
ID: 2641317
hello pasted from the rxlib :

function DaysPerMonth(AYear, AMonth: Integer): Integer;
const
  DaysInMonth: array[1..12] of Integer =
    (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
begin
  Result := DaysInMonth[AMonth];
  if (AMonth = 2) and IsLeapYear(AYear) then Inc(Result); { leap-year Feb is special }
end;

procedure DateDiff(Date1, Date2: TDateTime; var Days, Months, Years: Word);
{ Corrected by Anatoly A. Sanko (2:450/73) }
var
  DtSwap: TDateTime;
  Day1, Day2, Month1, Month2, Year1, Year2: Word;
begin
  if Date1 > Date2 then begin
    DtSwap := Date1;
    Date1 := Date2;
    Date2 := DtSwap;
  end;
  DecodeDate(Date1, Year1, Month1, Day1);
  DecodeDate(Date2, Year2, Month2, Day2);
  Years := Year2 - Year1;
  Months := 0;
  Days := 0;
  if Month2 < Month1 then begin
    Inc(Months, 12);
    Dec(Years);
  end;
  Inc(Months, Month2 - Month1);
  if Day2 < Day1 then begin
    Inc(Days, DaysPerMonth(Year1, Month1));
    if Months = 0 then begin
      Dec(Years);
      Months := 11;
    end
    else Dec(Months);
  end;
  Inc(Days, Day2 - Day1);
end;

function MonthsBetween(Date1, Date2: TDateTime): Double;
var
  D, M, Y: Word;
begin
  DateDiff(Date1, Date2, D, M, Y);
  Result := 12 * Y + M;
  if (D > 1) and (D < 7) then Result := Result + 0.25
  else if (D >= 7) and (D < 15) then Result := Result + 0.5
  else if (D >= 15) and (D < 21) then Result := Result + 0.75
  else if (D >= 21) then Result := Result + 1;
end;

this should be it...
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2641370
I think this is better and 100% accurate:

procedure TForm1.Button1Click(Sender: TObject);
var Date1, Date2: TDateTime;
    y1, y2, m1, m2, d1, d2: Word;
begin
  Date1 := Round(MonthCalendar1.Date);
  Date2 := Round(MonthCalendar2.Date);
  DecodeDate(Date1, y1 , m1, d1);
  DecodeDate(Date2, y2 , m2, d2);
  Label1.Caption := IntToStr(m2 - m1) + ' months between the two dates';
  Label2.Caption := FloatToStr((Date2 - Date1))
                  + ' days between the two dates';
end;
0
 

Author Comment

by:binho
ID: 2641491
Epsylon:
I don't think this works. If I take 31-jan-2000 as Date1 and 01-feb-2000 as Date2, the code you wrote returns 1 months, but it's wrong!...
And if I take 01-jan-2000 and 15-jan-2001, it returns 0 months, but it should be 12...

Jeurk:
If I have a 29 day february, I have a problem with your code...
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 4

Expert Comment

by:jeurk
ID: 2641530
Why ? the fact is handled with :
if (AMonth = 2) and IsLeapYear(AYear) then Inc(Result); { leap-year Feb is special }  No ?
Still a problem ?
0
 
LVL 13

Accepted Solution

by:
Epsylon earned 50 total points
ID: 2641752
I modified it a little bit. May still not be what you want:

procedure TForm1.Button1Click(Sender: TObject);
var Date1, Date2: TDateTime;
    y1, y2, m1, m2, d1, d2: Word;
begin
  Date1 := Trunc(MonthCalendar1.Date);
  Date2 := Trunc(MonthCalendar2.Date);
  DecodeDate(Date1, y1 , m1, d1);
  DecodeDate(Date2, y2 , m2, d2);
  m1 := y1 * 12 + m1;
  m2 := y2 * 12 + m2;
  if (m1 <> m2) and (d1 > d2) then
    Inc(m1);
  Label1.Caption := IntToStr(m2 - m1) + ' months between the two dates';
  Label2.Caption := FloatToStr((Date2 - Date1)) + ' days between the two dates';
end;
0
 

Author Comment

by:binho
ID: 2642216
Epsylon worked out fine...
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2642265
I hope you're right  :o)

I did some testing but not excessively.

Cheers.
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question