|
#1
|
|||
|
|||
Datetimepicker
народ, нужна помощь!!
надо посчитать разницу двух дат (Datetimepicker - 1,2), чтобы в ответе указать сколько лет, сколько месяцев и сколько дней между двух указанных дат!!! например, 06.01.1980 (Datetimepicker1) - 01.01.1982 (Datetimepicker2) ответ должно быть так: 1 год 11 месяцев 26 дней я пробовал так: Form1.Edit1.Text:=inttostr(trunc(Form1.datetimepic ker2.date)-(Form1.datetimepicker1.date)); но мой ответ выходить только разницы по дням Заранее спасибо!!! |
#2
|
||||
|
||||
А как ты себе представляешь разницу дат в твоем виде? Годы бывают високосными, в месяцах не одинаковое количество дней. Так что разницу можно получить только в днях.
Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
#3
|
|||
|
|||
Цитата:
Похоже, что для отдела кадров. Все зависит от конкретной задачи. Если в общем случае, все равно придется писать ручками свой инструментарий. Потому что придется учитывать праздничные и выходные дни, а также - их переносы ... Вероятно, надо вести какой-то внутренний календарь, "пробегать" период по месяцам и вычислять самому. Если же без календаря, то может быть помогут такие функции (когда-то для ОК писАл) : Код:
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; |