Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.11.2014, 05:35   #1
Simply-Art
Программист и
Участник клуба
 
Аватар для Simply-Art
 
Регистрация: 29.10.2006
Сообщений: 1,265
По умолчанию Вычисление даты (Delphi)

В переменной DT содержится текущая дата. Есть некоторое расписание. Расписание сохранено в виде числа меньше 128. Поясню, я кодировал дни недели так: пн-1, вт-2, ср-4, чт-8, пт-16, сб-32, вс-64.
По итогу нужно посмотреть, является ли текущая дата, датой обновления в расписании. Если нет, то нужно вычислить ближайшую предыдущий запланированную дату.
Например. Сегодня 18.11.2014. Переменная расписания содержит число 21. Это значит что обновление должно быть пн,ср,пт. Сегодня вторник. Ближайшее предыдущие число по расписанию 17.11.2014 (пн).
Помогите с кодом пожалуйста. Единственное что я смог сделать, это код декодирования дня недели в массив.
Код:
var
 daymass:array[1..7] of Boolean;
 DT:TDateTime;

procedure DecodeDay(DayCode:byte);
begin
if DayCode-64>=0 then
 begin
  DayCode:=DayCode-64;
  daymass[1]:=true;
 end;
if DayCode-32>=0 then
 begin
  DayCode:=DayCode-32;
  daymass[7]:=true;
 end;
if DayCode-16>=0 then
 begin
  DayCode:=DayCode-16;
  daymass[6]:=true;
 end;
if DayCode-8>=0 then
 begin
  DayCode:=DayCode-8;
  daymass[5]:=true;
 end;
if DayCode-4>=0 then
 begin
  DayCode:=DayCode-4;
  daymass[4]:=true;
 end;
if DayCode-2>=0 then
 begin
  DayCode:=DayCode-2;
  daymass[3]:=true;
 end;
if DayCode-1>=0 then
 begin
  DayCode:=DayCode-1;
  daymass[2]:=true;
 end;
end;
И да, как можно заметить, неделя начинается с воскресенья, это нормально.

Последний раз редактировалось Simply-Art; 18.11.2014 в 05:38.
Simply-Art вне форума Ответить с цитированием
Старый 18.11.2014, 07:22   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А если разложением?:
Код:
n:=21;i:=1;k:=1;
While i<64 do begin
  daymass[k]:=n and i;
  inc(k); i:=i shl 1;
end;
Цитата:
как можно заметить, неделя начинается с воскресенья, это нормально.
Это вопрос или нормально?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.11.2014, 07:28   #3
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

k := 0;
Код:
while DayCode > 0 do begin
    Inc(k);
    DayCode := DayCode shr 1
end;
daymass[k-1] := true;
Не?

Цитата:
Помогите с кодом пожалуйста.
А че сделать-то надо?
Я прально понимаю, что берем некую переменную, где записано число, когда должно быть пересчитано расписание.. Берем Min(текущая дата; дата, дата, когда должно быть пересчитано расписание)..
А потом идет от понедельника до Min и выводим все дни, по которым бежим.. не?
Poma][a вне форума Ответить с цитированием
Старый 18.11.2014, 08:44   #4
Simply-Art
Программист и
Участник клуба
 
Аватар для Simply-Art
 
Регистрация: 29.10.2006
Сообщений: 1,265
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Это вопрос или нормально?
Если бы был вопрос, я поставил бы его так что нормально.
Цитата:
Сообщение от Poma][a Посмотреть сообщение
А че сделать-то надо?
Я прально понимаю, что берем некую переменную, где записано число, когда должно быть пересчитано расписание.. Берем Min(текущая дата; дата, дата, когда должно быть пересчитано расписание)..
А потом идет от понедельника до Min и выводим все дни, по которым бежим.. не?
Нужно вычислить ближайшую предыдущий запланированную дату, исходя из текущей даты и расписания. Текущая дата тоже может быть запланированной.
Simply-Art вне форума Ответить с цитированием
Старый 18.11.2014, 10:14   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
function AnalysisDate(dt: TDateTime; DayCode: Byte; var NearestDate: TDateTime): Boolean;
var i,k,xDayDt,xDayNr: Byte;
begin
  Result:=True;
  xDayDt:=DayOfTheWeek(dt);
  k:=64;
  xDayNr:=0;
  for i:=7 downto 1 do begin
    if DayCode>=k then begin
      if xDayDt=i then Exit;
      if (xDayNr=0) or ((i<xDayDt) and (xDayNr>xDayDt)) then xDayNr:=i;
      Dec(DayCode,k);
    end;
    k:=k shr 1;
  end;
  NearestDate:=IncDay(dt,xDayNr-xDayDt);
  if xDayNr>xDayDt then NearestDate:=IncDay(NearestDate,-7);
  Result:=False;
end;

var xDate: TDateTime;
...
  if AnalysisDate(EncodeDate(2014,11,18),21,xDate)
    then ShowMessage('Дата по расписанию')
    else ShowMessage(Format('Ближайшая дата %s',[DateToStr(xDate)]));
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 18.11.2014, 10:30   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Если бы был вопрос, я поставил бы его так что нормально.
Ну извини, не понял. Я привык жить по германской дате.
Так мой совет подошел? Или я окончательно не понял сути вопроса?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 19.11.2014, 04:12   #7
Simply-Art
Программист и
Участник клуба
 
Аватар для Simply-Art
 
Регистрация: 29.10.2006
Сообщений: 1,265
По умолчанию

Работой завалили, пока некогда проверить, постараюсь в ближайшее время все посмотреть и отписаться.
Simply-Art вне форума Ответить с цитированием
Старый 19.11.2014, 09:18   #8
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

А я вот так попробую:
Код:
uses Types, SysUtils, DateUtils;

{ Кодирование дней недели: 2^(N - 1),
    N - номер дня недели:
        1 - пнд, 00000001
        2 - втр, 00000010
        3 - срд, 00000100
        4 - чтв, 00001000
        5 - птн, 00010000
        6 - сбт, 00100000
        7 - вск. 01000000
}

// функция выдаёт ближайшую, начиная с сегодняшней, дату,
// попадающую под маску недельного расписания.
function GetNearDate(const Mask: Byte): TDate;
var
  dow: Byte;
begin
  if Mask and $7F = 0
    then raise EConvertError.Create('WTF?');
    
  Result:= Date();

  repeat
    dow:= (DayOfTheWeek(Result) and $07) - 1; // dow = 0...6

    if Mask and (1 shl dow) <> 0
      then Exit;

    Result:= Result + 1.0;
  until False;
end;
Ахтунг! Не отлаживал, надиктовал устно секретутке.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Запрос на вычисление даты DAN1L SQL, базы данных 2 26.05.2013 17:41
вычисление даты, на которую приходится первая среда месяца Святой Дьявол Microsoft Office Excel 4 26.10.2011 16:11
Delphi.Даты specnazkin Помощь студентам 1 28.11.2010 09:53
Вычисление даты в зависимости от суммы sanantoni Microsoft Office Excel 2 17.09.2009 16:42
Вычисление даты завтрашнего дня meteora Помощь студентам 3 18.01.2008 11:18