delphi - How to avoid TDateTime Data Rounding -
i writing column , cell classes fmx tgrid
contain tcalendaredit
, ttimeedit
instances in every cell. works fine except proper processing of changes done in these child controls.
type tfmtvalue<t> = record fieldvalue: t; modified: boolean; appended: boolean; deleted: boolean; end; tdatetimecell = class(tstyledcontrol) private fdate_time: tfmtvalue<tdatetime>; procedure setdatetime(const value: tfmtvalue<tdatetime>); function getdatetime: tfmtvalue<tdatetime>; protected procedure setdata(const value: tvalue); override; public property date_time: tfmtvalue<tdatetime> read getdatetime write setdatetime; ... end; ... function tdatetimecell.getdatetime: tfmtvalue<tdatetime>; begin fdate_time.modified := (fdate_time.modified) or (fdate_time.fieldvalue <> fcalendaredit.date + + ftimeedit.time); fdate_time.fieldvalue := fcalendaredit.date + ftimeedit.time; result := fdate_time; end; procedure tdatetimecell.setdata(const value: tvalue); begin date_time := value.astype<tfmtvalue<tdatetime>>; inherited setdata(tvalue.from<tdatetime>(fdate_time.fieldvalue)); applystyling; end; procedure tdatetimecell.setdatetime(const value: tfmtvalue<tdatetime>); begin fdate_time := value; fcalendaredit.date := dateof(fdate_time.fieldvalue); ftimeedit.time := timeof(fdate_time.fieldvalue); fdate_time.fieldvalue:=fcalendaredit.date + ftimeedit.time; //this line helps not in cases end;
the idea data assigned via tgrid
ongetvalue
event handler. both date , time displayed. user activity catched , modified
flag set. problem flag set true without user activities. suspect due rounding of time part of tdatetime. there no other ways code assignes values fcalendaredit.date
, ftimeedit.time
.
how can compare data stored in fcalendaredit.date
, ftimeedit.time
stored in fdate_time.fieldvalue
?
appended
setting flag in way not resolve issue.
fdate_time.modified := (fdate_time.modified) or (dateof(fdate_time.fieldvalue) <> fcalendaredit.date) or (timeof(fdate_time.fieldvalue)<> ftimeedit.time);
appended 2. on valued advice of @ken-white. if replace comparison line by
fdate_time.modified := (fdate_time.modified) or (not samedatetime(fdate_time.fieldvalue, fcalendaredit.date + ftimeedit.time));
it works fine. tdatatime comparison must done function only.
tdatetime
of type double
, means it's floating point value, , therefore subject usual issues of binary representation when doing comparisons equality without specifying acceptable delta (difference)..
specifically tdatetime
values, can use dateutils.samedatetime
compare equality down less 1 millisecond:
fdate_time.modified := (fdate_time.modified) or (not samedatetime(fdate_time.fieldvalue, fcalendaredit.date + ftimeedit.time));
Comments
Post a Comment