[Lazarus] DateDif function needed

Bart bartjunk64 at gmail.com
Mon Nov 11 23:11:45 CET 2013


On 11/11/13, Michael Schnell <mschnell at lumino.de> wrote:

First try at it:
(Only works for correct Gregorian dates).

uses Classes, SysUtils, DateUtils;

type
  TDaysPerMonth = Array[1..12] of Word;


function DaysPerMonth(AMonth: Word; IsLeapYear: Boolean): Word;
const
  DaysPerMonthNormal: TDaysPerMonth = (31,28,31,30,31,30,31,31,30,31,30,31);
  DaysPerMonthLeap:   TDaysPerMonth = (31,29,31,30,31,30,31,31,30,31,30,31);
begin
  if IsLeapYear then
    Result := DaysPerMonthLeap[AMonth]
  else
   Result := DaysPerMonthNormal[AMonth];
end;

procedure DateDiff(Date1, Date2: TDate; out Years, Months, Days: Word);
var
  //Reverse: Boolean;
  Y1, Y2, M1, M2, D1, D2: word;

  procedure SwapDates(var D1, D2: TDate);
  var
    TempD: TDate;
  begin
    TempD := D1;
    D1 := D2;
    D2 := TempD;
  end;

begin
  if (Date1 > Date2) then
  begin
    SwapDates(Date1, Date2);
    //Reverse := True;
  end
  else
    //Reverse := False;
  Days := 0;
  Months := 0;
  Years := 0;
  DecodeDate(Date1, Y1, M1, D1);
  DecodeDate(Date2, Y2, M2, D2);
  Years := Y2 - Y1;
  if (M1 > M2) or ((M1 = M2) and (D1 > D2)) then Dec(Years);
  if (M1 > M2) then Inc(M2, 12); //already adjusted Years in that case
  Months := M2 - M1;
  if (D2 >= D1) then
    Days := D2 - D1
  else
  begin
    //writeln('D2 < D1');
    if (Months = 0) then
      Months := 11
    else
      Dec(Months);
    //writeln('DaysPerMonth(',M1,') = ',DaysPerMonth(M1, IsLeapYear(Y2)));
    Days := (DaysPerMonth(M1, IsLeapYear(Y2)) - D1) + D2 ;
  end;
end;

Bart




More information about the Lazarus mailing list