|
|
Регистрация | << Правила форума >> | 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; И т.д. |