Como evitar o arredondamento de dados TDateTime
Estou escrevendo classes de coluna e célula para FMXTGrid
que conteráTCalendarEdit
eTTimeEdit
instâncias em cada célula. Tudo funciona bem, exceto o processamento adequado das alterações feitas nesses controles filho.
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 but not in all cases
end;
A idéia é que os dados sejam atribuídos viaTGrid
OnGetValue
manipulador de eventos. Data e hora são exibidas. A atividade do usuário é capturada eModified
sinalizador está definido. O problema é que esse sinalizador é definido como verdadeiro às vezes, mesmo sem nenhuma atividade do usuário. Eu suspeito que é devido ao arredondamento do tempo parte do TDateTime. Não há outras maneiras pelas quais o código atribui valores aFCalendarEdit.Date
eFTimeEdit.Time
.
Como posso comparar adequadamente os dados armazenados noFCalendarEdit.Date
eFTimeEdit.Time
com aquele armazenado emFDate_Time.FieldValue
?
Anexado
Definir o sinalizador dessa maneira não resolve o problema.
FDate_Time.Modified := (FDate_Time.Modified) or
(DateOf(FDate_Time.FieldValue) <> FCalendarEdit.Date) or
(TimeOf(FDate_Time.FieldValue)<> FTimeEdit.Time);
Anexo 2. Seguindo um conselho valioso de @ Ken-White. Se substituirmos a linha de comparação por
FDate_Time.Modified := (FDate_Time.Modified) or
(not SameDateTime(FDate_Time.FieldValue,
FCalendarEdit.Date + FTimeEdit.Time));
Funciona bem. Portanto, a comparação do TDataTime deve ser feita apenas por esta função.