![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Здравствуйте! Написал функции перевода даты в дни, начиная с 1 января какого-либо года
Код:
const
BeginYear = 2006;
ShiftYear = 4 - BeginYear mod 4; // сдвиг года к високосному
var
MonthDays: array [0..12] of Word =
(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
function DateToDays(const Year, Month, Day: Word): Cardinal;
var
i, Days: Cardinal;
begin
// число дней
Days := Day;
// пересчет месяцев в дни
for i := 1 to Month-1 do
Inc(Days, MonthDays[i]);
// пересчет лет в дни
Days := Days + Year*365 + ((Year+ShiftYear) div 4) - 1;
// если високосный и месяц январь или февраль
if (((Year+ShiftYear) mod 4) = 0 ) and (Month <= 2) then
Dec(Days); // убираем день
result := Days;
end;
procedure DaysToDate(const CodeDate: Cardinal; var Year, Month, Day: Word);
var
Years, i: Cardinal;
Days: Integer;
begin
Years := CodeDate div 365;
Days := CodeDate mod 365 - ((Years+ShiftYear-1) div 4);
if Days < 0 then
begin
Dec(Years);
Days := Days + 365;
if ((Years+ShiftYear) mod 4) = 0 then
Inc(Days);
end;
if (((Years + BeginYear) mod 4) = 0) and (Days >= 31+29) then
Dec(Days);
Year := Years;
for i:=1 to 12 do
if Days >= MonthDays[i] then
Dec(Days, MonthDays[i])
else
begin
Month := i;
break;
end;
Day := Days+1;
end; |
|
#2
|
|||
|
|||
|
В модуле DateUtils есть функция DaysBetween.
а если внимательно посмотреть на представление типа TDateTime, то можно увидеть, что кол-во дней между 2мя датами можно получить простым вычитанием из одной даты другой (это тип с фиксированной точкой, где целые числа представляют кол-во дней с некоторой определенной даты, а дробная часть - время). |
|
#3
|
|||
|
|||
|
Дело в том, что эти функции будет использовать абсолютно другой проек, в котором нет типа TDateTime
|
|
#4
|
|||
|
|||
|
Когда-то нашел (где-то) формулу, которая вычисляет кол-во дней от начала Григорианского календаря (по-моему, 15.10.1582-пятница).
В реализации на pascal выглядит так (тип real остался, как реликт, когда integer был 2-х байтовым): Код:
function Size_DateYMD(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 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(Size_DateYMD(Ye2,Mo2,Da2) - Size_DateYMD(Ye1,Mo1,Da1));
if Result<0 then begin
Result:=-1;
end;
end;
end;
end;
end;
И т.д. |