Solved

# of months between 2 dates

Posted on 2000-03-21
7
439 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
Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

 
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

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

803 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