Форум по Delphi программированию



Вернуться   Форум по Delphi программированию > Все о Delphi > Синтаксис
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 10.11.2010, 22:31
Drozh Drozh вне форума
Активный
 
Регистрация: 12.06.2008
Сообщения: 313
Репутация: 40
По умолчанию Перевод даты в дни

Здравствуйте! Написал функции перевода даты в дни, начиная с 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;
Так вот, все работет отлично, но постоянное появляется ошибка определения 29.02 любого високосного года =( В чем может быть ошибка? Может быть кто-нибудь сталкивался с подобной задачей?
Ответить с цитированием
  #2  
Старый 11.11.2010, 01:11
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,770
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

В модуле DateUtils есть функция DaysBetween.
а если внимательно посмотреть на представление типа TDateTime, то можно увидеть, что кол-во дней между 2мя датами можно получить простым вычитанием из одной даты другой (это тип с фиксированной точкой, где целые числа представляют кол-во дней с некоторой определенной даты, а дробная часть - время).
Ответить с цитированием
  #3  
Старый 11.11.2010, 07:30
Drozh Drozh вне форума
Активный
 
Регистрация: 12.06.2008
Сообщения: 313
Репутация: 40
По умолчанию

Дело в том, что эти функции будет использовать абсолютно другой проек, в котором нет типа TDateTime
Ответить с цитированием
  #4  
Старый 12.11.2010, 22:28
roamer roamer вне форума
Активный
 
Регистрация: 15.04.2009
Сообщения: 369
Репутация: 93
По умолчанию

Когда-то нашел (где-то) формулу, которая вычисляет кол-во дней от начала Григорианского календаря (по-моему, 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;


И т.д.
Ответить с цитированием
  #5  
Старый 12.11.2010, 22:35
roamer roamer вне форума
Активный
 
Регистрация: 15.04.2009
Сообщения: 369
Репутация: 93
По умолчанию

Цитата:
Сообщение от Drozh
Дело в том, что эти функции будет использовать абсолютно другой проек, в котором нет типа TDateTime
Может чем-то поможет._Date.zip
Ответить с цитированием
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 17:08.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2021

ВКонтакте   Facebook   Twitter   Ссылка на Telegram