Цитата:
Сообщение от Kara1989
... например, 06.01.1980 (Datetimepicker1) - 01.01.1982 (Datetimepicker2) ответ должно быть так: 1 год 11 месяцев 26 дней ...
|
Похоже, что для отдела кадров.
Все зависит от конкретной задачи.
Если в общем случае, все равно придется писать ручками свой инструментарий. Потому что придется учитывать праздничные и выходные дни, а также - их переносы ...
Вероятно, надо вести какой-то внутренний календарь, "пробегать" период по месяцам и вычислять самому.
Если же без календаря, то может быть помогут такие функции (когда-то для ОК писАл) :
Код:
function Get_CountDays_In_Year(Ye : integer) : integer;
//Кол-во дней в заданном году
begin
Result:=365;
if Ye>0 then begin
if IsLeapYear(Ye) then Result:=366;
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;
Кроме этого, могут быть случаи, когда для вычисления достаточно считать, что в месяце 30 дней (усредненно).
Тогда, может быть устроит такой подход (старая функция, но вроде бы рабочая) :
Код:
Const
Get_FirstYear_for_Greg = 1582; //самый первый год (Григорианского календаря), корректный для использования функций работы с датами
function Date2ymd_minus_Date1ymd_YMD_30(Ye1,Mo1,Da1, Ye2,Mo2,Da2 : integer;
Var DeltaY,DeltaM,DeltaD : integer) : boolean;
//Вычислисть разницу двух дат (кол-во лет, меясцев, дней)
//С учетом того, что в месяце 30 дней (усредненно)
Var
Nr : integer;
begin
Result:=false;
DeltaD := 0;
DeltaM := 0;
DeltaY := 0;
if IsDateYMD(Ye1,Mo1,Da1) then begin //проверяем Дата1 на корректность
if IsDateYMD(Ye2,Mo2,Da2) then begin //проверяем Дата2 на корректность
Nr:=Compare_Dates_YMD(Ye1,Mo1,Da1, Ye2,Mo2,Da2); //сравниваем период дат (провекрка на корректность)
if Nr<=0 then begin //Дата1 <= Дата2
Result:=true;
if Nr<0 then begin //Дата1 < Дата2
DeltaD:=Da2-Da1;
if DeltaD<0 then begin
Da2:=Da2+30; //Считаем, что в месяце 30 дней
Mo2:=Mo2-1;
end;
DeltaD:=Da2-Da1;
DeltaM:=Mo2-Mo1;
if DeltaM<0 then begin
Mo2:=Mo2+12;
Ye2:=Ye2-1;
end;
DeltaM:=Mo2-Mo1;
DeltaY:=Ye2-Ye1;
end;
end;
end;
end;
end;
function Get_IDDateYMD(Y,M,D : integer) : integer;
//Вычислить ID даты (YMD)
begin
Result:=Y*10000+M*100+D;
end;
function IsDateYMD(Ye,Mo,Da : integer) : boolean;
//Проверить корректность даты YMD
begin
Result:=false;
if (Ye>=Get_FirstYear_for_Greg) 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 Compare_Dates_YMD(Ye1,Mo1,Da1,Ye2,Mo2,Da2 : integer) : integer;
//26.05.2009
{Сравнение дат}
//Дата1: Ye1,Mo1,Da1 (год,мес,день)
//Дата2: Ye2,Mo2,Da2 (год,мес,день)
Var
id1,id2 : integer;
begin
Result:=-99; //Ошибка
id1:= Get_IDDateYMD(Ye1,Mo1,Da1);
id2:= Get_IDDateYMD(Ye2,Mo2,Da2);
if (id1>0) and (id2>0) then begin
Result:=0; //Даты равны
if id1>id2 then begin
Result:=1; //Дата1>Дата2
end
else begin
if id1<id2 then begin
Result:=-1; //Дата1<Дата2
end;
end;
end;
end;
|