-
Для чего нужна фукнция CompareDate\Time если TDateTime можно сравнить напрямую как Double?
-
точность дабла выше чем требуется
-
а также у дабла ошибок меньше, чем требуется
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;
-
ошибки здесь не при делах.
с одной стороны это дабл и 15 значащих, с другой стороны у нас геттиккаунт, декоде/енкодетайм и т.д, которые только до миллисекунд время понимают.
и вот типа я хочу написать шедулер с точностью до миллисекунды. но сравнивая дабл, я не получу равенства, и евент запланированный на 00:00:00:000 реально сработает только в 00:00:00:001
-
не понятны мне слова твои, код лучше понимаю я
-
как это можно не понять:
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;
-
чо тут непонятного?
физически дэйттам - дабл. логически - целый тип с точностью до миллисекунды.
А КомпареДэйтТайм дана нам чтобы у нас иногда были одинаковые (логически) величины времени.
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 Хотя на самом деле не равно')
-
короче. если бы не было КомпареДэйтТайм, то имея тип времени с точностью до одной миллисекунды, мы реально бы имели точность до двух миллисекунд, то есть в два раза хуже чем задумано типом данных.
например пример выше.
евент запланирован на 00:00:00:000
крутимся в цикле ожидания, оперируя даблом. так как сравнивать дабл на равенство смысла ноль, то мы будем ждать тово вызова гетсустем тайм, когда оно в даббл будет больше 00:00:00:000 (или меньше)
в итоге наш шедулер сработает не в заданное время, а +/- одна миллисекунда. хотя типа в два раза точнее
-
>хотя тип TDateTime в два раза точнее
-
Проникся мыслью я твоей и воплотить решился Компаратор. Но прежде пытку учинил ему.
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;
Не хочет подлая собака служить мне. Заставить как его работать, дай мне совет.
-
как оно работает - вопрос десятый. главный вопрос зачем оно.
а оно затем же самым зачем и деньги. с одной стороны ты взял кредит в N рублей под M.N % и должен банку xyz.zyx рублей.
и бабки (в основном) вещественными программируются.
а с другой стороны реальный гривенник в кассе не распилишь - оно атомарное существо.
и как вам с кассиром разойтись полюбовно, если в банк-софте не будет надстройки над вещественным currency огрубляющим его до копеек?
-
Опять же мысль твоя понятна и нужность вещи сей неоспорима. Но пользы не приносит нам она, покуда нет у нас знаний.
-
> Кто б сомневался © (01.03.17 05:51) > Для чего нужна фукнция CompareDate\Time если TDateTime можно > сравнить напрямую как Double?
Как ты будешь проверять на равенство два Double ? D1 = D2 ??? Вот и ответ зачем нужна функция.
-
DVM © (01.03.17 15:25) [12]
Дело в том, что проверки эти требуется выполнять каждый раз по-разному в зависимости от контекста, который известен программисту.
Вот и ответ, почему она не только не нужна, но и вредна, т.к. у программиста больше шансов не обратить внимание на контекст.
-
Советую забыть про эту абоминацию TDateTime и пользоваться GetLocalTime. Там все числа целые и сравниваются всегда корректно.
-
Спасибо :)
-
и чем оно другее, с учетом тово, что это ровно тоже самое тютя-в-тютю?
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';
-
> и чем оно другее
Тем, что TSystemTime можно сравнивать не прибегая к перекодированию в double. А если очень хочется, то можно это упаковать в Int64 и сравнивать его.
-
TDateTime тоже можно сравнивать тупым = не прибегая к оберткам.
-
var d : TDateTime; i : integer; begin d := now; i := 0; while d = now do inc(i); ShowMessage(IntToStr(i));
пока значения TDateTime рождаются через функции этого типа, точности дабл с горкой хватает для сравнения TDateTime простым "=".
-
-
> Sha © (02.03.17 09:14) [20] > > > Кто б сомневался > > Для полноты картины и я скажу
Не стоит ли нам ожидать второго тома "Неочевидные особенности..." на сей раз под авторством А.Шарахова? Имхо, не помешало бы. :)
-
Ремейки хуже оригинала, так что не буду даже пытаться. А вот там по ссылочке на статью (John Herbster) очень советую сходить. Он давно занимается именно этим вопросом.
Что меня просто пугает в обсуждаемых функциях - их нетранзитивность. В общем случае такие функции сравнения нельзя использовать в алгоритмах сортировки, хотя их интерфейс просто подталкивает именно к такому использованию.
-
> Sha © (01.03.17 15:53) [13] > Дело в том, что проверки эти требуется выполнять каждый раз по-разному > в зависимости от контекста, который известен программисту. > > Вот и ответ, почему она не только не нужна, но и вредна
Странное заявление. Функция имеет документированное поведение. Понять, подходит ли поведение функции под имеющиеся задачи - задача программиста. Если кто-то применил инструмент (функцию) не по назначению - странно пенять на инструмент.
-
> KSergey © (03.03.17 12:09) [23] > Странное заявление. > Функция имеет документированное поведение. > Понять, подходит ли поведение функции под имеющиеся задачи - задача программиста. > Если кто-то применил инструмент (функцию) не по назначению - странно пенять на инструмент.
Заявление нормальное. А вот документация странная.
Это как если бы производитель арахисовых батончиков на упаковке просто написал бы "Батончик ореховый, вкусный и питательный". А ребенок с аллергией на арахис слопал бы его, ничего не подозревая.
Программисты бывают разные, некоторые как дети.
-
> Sha © (03.03.17 09:28) [22] > А вот там по ссылочке на статью (John Herbster) очень советую > сходить.
Ссылочка, к сожалению уже не работает. Прошло 7 с лишком лет. А поисковики, к сожалению эту статью не находят, кроме как упоминания о ней в твоём блоге и твоих постах на ДК.
-
Меня только смущают замечания о некорректной/неправильной работе этих функций при отрицательных значениях Даты/времени.
-
> Это как если бы производитель арахисовых батончиков на упаковке > просто написал бы "Батончик ореховый, вкусный и питательный". >
так и пишут. а потом состав (на конфетах- крайне редко)
-
> Sha © (01.03.17 15:53) [13]
> Дело в том, что проверки эти требуется выполнять каждый > раз по-разному > в зависимости от контекста, который известен программисту. >
> Вот и ответ, почему она не только не нужна, но и вредна,
Брось. Кому нужна своя функция, напишет свою. Это не повод объявлять вредным всё, что имеет более одного варианта реализации.
|