{ --------------------------------------------------------------- }
{ Dieser Quelltext ist urheberrechtlich geschuetzt.               }
{ (c) 2006-2012      Martin Wodrich, http://www.martinwodrich.de  }
{ (c) 2008-2024      FreeXP, http://www.freexp.de                 }
{                                                                 }
{ Dieser Quelltext ist Freeware.                                  }
{                                                                 }
{ Die allgemeinen Nutzungsbedingungen fuer diesen Quelltext       }
{ finden Sie in der Datei TOUCH.TXT oder auf                      }
{ http://www.martinwodrich.de/Software/Touch/nutzung.htm          }
{ --------------------------------------------------------------- }

unit dtdiff;

interface
{$I TOUCH.INC }

function calcdt(org:longint; yy,mm,dd,hh,mi,ss:word; direction:boolean):longint;

implementation

{$IFDEF Win16 }
uses windos;

var
dt          :TDateTime;
{$ELSE}
{$IFNDEF PASCALABC}
uses dos;
{$ENDIF}
var
dt          : DateTime;
{$ENDIF}

const
    DaysInMonth: array[0..1,1..12] of integer =
      ((31,28,31,30,31,30,31,31,30,31,30,31),   {normales Jahr}
       (31,29,31,30,31,30,31,31,30,31,30,31));  {Schaltjahr}

function schalt:byte;  {Schaltjahr?}
begin
  if (((dt.Year mod 4) = 0) and
      ((dt.Year mod 100) <> 0)) or
      ((dt.Year mod 400)=0) then schalt:=1
  else schalt:=0;
end;

function calcdtf(org:longint; yy,mm,dd,hh,mi,ss:word):longint;  {+}

begin
  Unpacktime(org,dt);
  dt.Sec:=dt.Sec+ss;
  if dt.Sec>59 then begin
    dt.Min:=dt.Min+(dt.Sec div 60);
    dt.Sec:=dt.Sec mod 60;
  end;
  dt.Min:=dt.Min+mi;
  if dt.Min>59 then begin
    dt.Hour:=dt.Hour+(dt.Min div 60);
    dt.Min:=dt.Min mod 60;
  end;
  dt.Hour:=dt.Hour+hh;
  if dt.Hour>23 then begin
    dt.Day:=dt.Day+(dt.Hour div 24);
    dt.Hour:=dt.Hour mod 24;
  end;
  dt.Day:=dt.Day+dd;
  while dt.Day>DaysInMonth[schalt,dt.Month] do
  begin
    dt.Day:=dt.Day-DaysInMonth[schalt,dt.Month];
    inc(dt.Month);
    if dt.Month>12 then
    begin
      inc(dt.Year);
      dt.Month:=1;
    end;
  end;
  dt.Month:=dt.Month+mm;
  while dt.Month>12 do
  begin
    inc(dt.Year);
    dt.Month:=dt.Month-12;
  end;
  dt.Year:=dt.Year+yy;
  if dt.Day>DaysInMonth[schalt,dt.Month] then
  begin
    dt.Day:=dt.Day-DaysInMonth[schalt,dt.Month];
    inc(dt.Month);
    if dt.Month>12 then
    begin
      inc(dt.Year);
      dt.Month:=1;
    end;
  end;
  Packtime(dt,org);
  calcdtf:=org;
end;

function calcdth(org:longint; yy,mm,dd,hh,mi,ss:word):longint;  {-}

begin
  Unpacktime(org,dt);
  if ss>59 then begin
    mi:=mi+(ss div 60);
    ss:=ss mod 60;
  end;
  if dt.Sec<ss then begin
   inc(mi);
   dt.Sec:=dt.Sec+60;   
  end; 
  dt.Sec:=dt.Sec-ss;
  if mi>59 then begin
    hh:=hh+(mi div 60);
    mi:=mi mod 60;
  end;
  if dt.Min<mi then begin
    inc(hh);
    dt.Min:=dt.Min+60;    
  end;
  dt.Min:=dt.Min-mi;
  if hh>23 then begin
    dd:=dd+(hh div 24);
    hh:=hh mod 24;
  end;
  if dt.Hour<hh then begin
    inc(dd);
    dt.Hour:=dt.Hour+24;    
  end; 
  dt.Hour:=dt.Hour-hh;
  while mm>12 do
  begin
    mm:=mm-12;
    inc(yy);
  end;
  dt.Year:=dt.Year-yy;
  if dt.Month<=mm then begin
    dec(dt.Year);
    dt.Month:=dt.Month+12;    
  end; 
  dt.Month:=dt.Month-mm;
  if dt.Day>dd then dt.Day:=dt.Day-dd
  else begin
    while dd>=dt.Day do
    begin      
      dec(dt.Month);
      if dt.Month=0 then begin
       dec(dt.Year);
       dt.Month:=12; 
      end;
      dt.Day:=DaysInMonth[schalt,dt.Month];
      dd:=dd-dt.Day;            
    end;
  end;
  Packtime(dt,org);
  calcdth:=org;
end;

function calcdt(org:longint; yy,mm,dd,hh,mi,ss:word; direction:boolean):longint;
begin
  if direction then calcdt:=calcdtf(org,yy,mm,dd,hh,mi,ss)
  else calcdt:=calcdth(org,yy,mm,dd,hh,mi,ss);
end;

begin
end.
