Const
Date_GrigFirstYear = 1582;//самый первый год (Григорианского календаря), корректный для использования функций работы с датами
Date_GrigFirstDate = '15.10.1582' {пятница}; //самая первая дата (Григорианского календаря), корректная для использования функций работы с датами
function Date2str_minus_Date1str(sDate1, sDate2 : string) : integer;
{Кол-во дней между датами в формате String}
Var
Ye1,Mo1,Da1,
Ye2,Mo2,Da2 : integer;
begin
Result:=-1;
if DateStr_to_DateYMD(sDate1,Ye1,Mo1,Da1) then begin
if DateStr_to_DateYMD(sDate2,Ye2,Mo2,Da2) then begin
Result:=Date2ymd_minus_Date1ymd(Ye1,Mo1,Da1,Ye2,Mo2,Da2);
end;
end;
end;
function Date2ymd_minus_Date1ymd(Ye1,Mo1,Da1, Ye2,Mo2,Da2 : integer) : integer;
{Кол-во дней между датами в формате YMD}
begin
Result:=-1;
if IsDateYMD(Ye1,Mo1,Da1) then begin //дата-1 корректна
if IsDateYMD(Ye2,Mo2,Da2) then begin //дата-2 корректна
if Get_IDDateYMD(Ye1,Mo1,Da1)<=Get_IDDateYMD(Ye2,Mo2,Da2) then begin
//период дат корректен
//Вычисляем кол-во дней между датами
Result:=trunc(DateYMD_Size(Ye2,Mo2,Da2) - DateYMD_Size(Ye1,Mo1,Da1));
if Result<0 then begin
Result:=-1;
end;
end;
end;
end;
end;
function DateYMD_Size(Ye,Mo,Da : integer) : real;
//"Размер" Даты
Var
BufY,BufM,BufD : real;
begin
Result:=0;
BufY:=Ye;
BufM:=Mo;
BufD:=Da;
if (Mo>0) and (Mo<=2) then begin
Result := trunc(365*BufY)
+ trunc(BufD)
+ trunc(31*(BufM-1))
+ trunc((BufY-1)/4)
- trunc(3/4*(trunc(BufY-1)/100+1));
end;
if (Mo>2) and (Mo<=12) then begin
Result := trunc(365*BufY)
+ trunc(BufD)
+ trunc(31*(BufM-1))
- trunc(0.4*BufM+2.3)
+ trunc(BufY/4)
- trunc(3/4*(trunc(BufY/100)+1));
end;
end;
function DateStr_to_DateYMD(sDate : string; Var Ye,Mo,Da : integer) : boolean;
//Конвертировать дату из String в YMD
Var
DT : TDateTime;
Yw,Mw,Dw : word;
begin
Result:=false;
Ye:=0;
Mo:=0;
Da:=0;
sDate:=trim(sDate);
if length(sDate)>0 then begin
if SysUTILS.TryStrToDate(sDate,DT) then begin
Result:=true;
DecodeDate(DT, Yw, Mw, Dw);
Ye:=Yw;
Mo:=Mw;
Da:=Dw;
end;
end;
end;
function DateStr_Size(sDate : string) : real;
//"Размер" Даты в формате Строка
Var
Ye,Mo,Da : integer;
begin
Result:=0;
if DateStr_to_DateYMD(sDate, Ye,Mo,Da) then begin
Result:=DateYMD_Size(Ye,Mo,Da);
end;
end;
function IsDateYMD(Ye,Mo,Da : integer) : boolean;
//Проверить корректность даты YMD
begin
Result:=false;
if (Ye>=Date_GrigFirstYear) then begin
if (Ye<=3100) then begin
if (Mo>0) and (Mo<=12) then begin
if (Da>0) then begin
if (Da<=Get_CountDays_In_Month(Ye,Mo)) then begin
Result:=true;
end;
end;
end;
end;
end;
end;
function Get_CountDays_In_Month(Ye, Mo : integer) : integer;
//Кол-во дней в заданном месяце
begin
Result:=0;
if Ye>0 then begin
if (Mo>0) and (Mo<=12) then begin
Result:=30;
if Mo=2 then begin
Result:=28;
if IsLeapYear(Ye) then Result:=29;
end
else begin
if (Mo in [1,3,5,7,8,10,12]) then Result:=31;
end;
end;
end;
end;
function Get_IDDateYMD(Y,M,D : integer) : integer;
//Вычислить ID даты (YMD)
begin
Result:=Y*10000+M*100+D;
end;