Тема: Datetimepicker
Показать сообщение отдельно
  #3  
Старый 03.08.2009, 09:39
roamer roamer вне форума
Активный
 
Регистрация: 15.04.2009
Сообщения: 369
Репутация: 93
По умолчанию

Цитата:
Сообщение от 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;
    
Ответить с цитированием