Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

# of months between 2 dates

Posted on 2000-03-21
7
Medium Priority
?
456 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
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 150 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: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

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

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…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

722 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