Конференция "Начинающим" » Для чего нужна ф. CompareDate\Time если TDateTime
 
  • Кто б сомневался © (01.03.17 05:51) [0]
    Для чего нужна фукнция CompareDate\Time если TDateTime можно сравнить напрямую как Double?
  • rrrrr © (01.03.17 08:41) [1]
    точность дабла выше чем требуется
  • Sha © (01.03.17 09:52) [2]
    а также у дабла ошибок меньше, чем требуется

    procedure TForm1.Button1Click(Sender: TObject);
    var
     dt1, dt2: TDateTime;
    begin;
     dt1:=-99.1;
     dt2:=-99.2;
     Memo1.Lines.Add(FormatDateTime('yyyy.mm.dd  hh:nn:ss.zzz',dt1));
     Memo1.Lines.Add(FormatDateTime('yyyy.mm.dd  hh:nn:ss.zzz',dt2));
     Memo1.Lines.Add(IntToStr(CompareDateTime(dt1,dt2)));
     end;
  • rrrrr © (01.03.17 10:18) [3]
    ошибки здесь не при делах.

    с одной стороны это дабл и 15 значащих, с другой стороны у нас геттиккаунт, декоде/енкодетайм и т.д, которые только до миллисекунд время понимают.

    и вот типа я хочу написать шедулер с точностью до миллисекунды.
    но сравнивая дабл, я не получу равенства, и евент запланированный на 00:00:00:000 реально сработает только в 00:00:00:001
  • Sha © (01.03.17 10:55) [4]
    не понятны мне слова твои, код лучше понимаю я
  • Sha © (01.03.17 11:01) [5]
    как это можно не понять:

    procedure TForm1.Button5Click(Sender: TObject);
    const
     Delta = OneMillisecond*0.999;
    var
     dt: array of TDateTime;
     i: integer;
    begin;
     SetLength(dt,3);
     dt[1]:=Now;
     dt[0]:=dt[1]-Delta;
     dt[2]:=dt[1]+Delta;
     QuickSort(dt,Low(dt),High(dt));
     for i:=Low(dt) to High(dt) do
     Memo1.Lines.Add(FormatDateTime('yyyy.mm.dd  hh:nn:ss.zzz', dt[i]));
     end;
  • rrrrr © (01.03.17 11:08) [6]
    чо тут непонятного?

    физически дэйттам - дабл.
    логически - целый тип с точностью до миллисекунды.

    А КомпареДэйтТайм дана нам чтобы у нас иногда были одинаковые (логически) величины времени.

    var dt1, dt2 : Double;
       h1,h2,m1,m2,s1,s2,ms1,ms2 : Word;
    begin
    dt1 := now();
    dt2 := dt1 + (OneMillisecond / 2);

    DecodeTime(dt1,h1,m1,s1,ms1);
    DecodeTime(dt2,h2,m2,s2,ms2);

    if CompareDateTime(dt1,dt2) = 0 then
     Memo1.Lines.Add(Format('Ну а как бы да, равно.%s %d=%d %d=%d %d=%d %d=%d %sА как иначе-то?'#13#10,[ #13#10, h1,h2,m1,m2,s1,s2,ms1,ms2,#13#10]));

    if dt1 <> dt2 then Memo1.Lines.Add('PS Хотя на самом деле не равно')
  • rrrrr © (01.03.17 11:29) [7]
    короче.
    если бы не было КомпареДэйтТайм,
    то
    имея тип времени с точностью до одной миллисекунды, мы реально бы имели точность до двух миллисекунд, то есть в два раза хуже чем задумано типом данных.

    например пример выше.

    евент запланирован на 00:00:00:000

    крутимся в цикле ожидания, оперируя даблом.
    так как сравнивать дабл на равенство смысла ноль,
    то мы будем ждать тово вызова гетсустем тайм, когда оно в даббл будет больше 00:00:00:000 (или меньше)

    в итоге наш шедулер сработает не в заданное время, а +/- одна миллисекунда.
    хотя типа в два раза точнее
  • rrrrr © (01.03.17 11:30) [8]
    >хотя тип TDateTime в два раза точнее
  • Sha © (01.03.17 11:47) [9]
    Проникся мыслью я твоей и воплотить решился Компаратор.
    Но прежде пытку учинил ему.

    procedure TForm1.Button3Click(Sender: TObject);
    var
     dt1, dt2: TDatetime;
     y, m, d, h, n, s, z: word;
     cnt: integer;
     t1, t2: string;
    begin;
     DecodeDatetime(Date, y, m, d, h, n, s, z);
     dt1:=Date-1;
     cnt:=0;
     for h:=0 to 23 do begin;
       for n:=0 to 59 do begin;
         for s:=0 to 59 do begin;
           for z:=0 to 999 do begin;
             dt2:=EncodeDatetime(y, m, d, h, n, s, z);
             if CompareDatetime(dt1, dt2)=0 then begin;
               inc(cnt);
               if cnt<100 then begin;
                 t1:=FormatDateTime('dd.mm.yyyy hh:nn:ss.zzz', dt1);
                 t2:=FormatDateTime('dd.mm.yyyy hh:nn:ss.zzz', dt2);
                 Memo1.Lines.Add(t1 + '  ' + t2);
                 end;
               end;
             dt1:=dt2;
             end;
           end;
         end;
       end;
     Memo1.Lines.Add(Format('%d раз равно', [cnt]));
     end;


    Не хочет подлая собака служить мне.
    Заставить как его работать, дай мне совет.
  • rrrrr © (01.03.17 11:56) [10]
    как оно работает - вопрос десятый.
    главный вопрос зачем оно.

    а оно затем же самым зачем и деньги.
    с одной стороны ты взял кредит в N рублей под M.N % и должен банку xyz.zyx рублей.

    и бабки (в основном) вещественными программируются.

    а с другой стороны реальный гривенник в кассе не распилишь - оно атомарное существо.

    и как вам с кассиром разойтись полюбовно,
    если в банк-софте не будет надстройки над вещественным currency огрубляющим его до копеек?
  • Sha © (01.03.17 12:04) [11]
    Опять же мысль твоя понятна и нужность вещи сей неоспорима.
    Но пользы не приносит нам она, покуда нет у нас знаний.
  • DVM © (01.03.17 15:25) [12]

    > Кто б сомневался ©   (01.03.17 05:51) 
    > Для чего нужна фукнция CompareDate\Time если TDateTime можно
    > сравнить напрямую как Double?

    Как ты будешь проверять на равенство два Double ?  D1 = D2 ???
    Вот и ответ зачем нужна функция.
  • Sha © (01.03.17 15:53) [13]
    DVM ©   (01.03.17 15:25) [12]

    Дело в том, что проверки эти требуется выполнять каждый раз по-разному
    в зависимости от контекста, который известен программисту.

    Вот и ответ, почему она не только не нужна, но и вредна,
    т.к. у программиста больше шансов не обратить внимание на контекст.
  • Dimka Maslov © (01.03.17 22:46) [14]
    Советую забыть про эту абоминацию TDateTime и пользоваться GetLocalTime. Там все числа целые и сравниваются всегда корректно.
  • Кто б сомневался © (01.03.17 23:19) [15]
    Спасибо :)
  • rrrrr © (01.03.17 23:19) [16]
    и чем оно другее, с учетом тово, что это ровно тоже самое тютя-в-тютю?

    function Now: TDateTime;
    {$IFDEF MSWINDOWS}
    var
     SystemTime: TSystemTime;
    begin
     GetLocalTime(SystemTime);
     Result := EncodeDate(SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay) +
       EncodeTime(SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds);
    end;

    procedure GetLocalTime(var lpSystemTime: TSystemTime); stdcall;
    ....
    procedure GetLocalTime; external kernel32 name 'GetLocalTime';
  • Dimka Maslov © (02.03.17 08:33) [17]

    > и чем оно другее


    Тем, что TSystemTime можно сравнивать не прибегая к перекодированию в double. А если очень хочется, то можно это упаковать в Int64 и сравнивать его.
  • rrrrr © (02.03.17 08:36) [18]
    TDateTime тоже можно сравнивать тупым = не прибегая к оберткам.
  • rrrrr © (02.03.17 08:42) [19]
    var d : TDateTime; i : integer;
    begin
    d := now; i := 0;
    while d = now do inc(i);
    ShowMessage(IntToStr(i));

    пока значения TDateTime рождаются через функции этого типа, точности дабл с горкой хватает для сравнения TDateTime простым "=".
 
Конференция "Начинающим" » Для чего нужна ф. CompareDate\Time если TDateTime
Есть новые Нет новых   [118608   +46][b:0][p:0.001]