So vermeiden Sie TDateTime-Datenrundung
Ich schreibe Spalten- und Zellenklassen für FMXTGrid
das wird @ enthaltTCalendarEdit
undTTimeEdit
Instanzen in jeder Zelle. Mit Ausnahme der ordnungsgemäßen Verarbeitung von Änderungen, die in diesen untergeordneten Steuerelementen vorgenommen wurden, funktioniert alles einwandfrei.
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;
Die Idee ist, dass Daten über @ zugewiesen werdTGrid
OnGetValue
Eventhandler. Sowohl Datum als auch Uhrzeit werden angezeigt. Die Benutzeraktivität wird abgefangen undModified
flag ist gesetzt. Das Problem ist, dass dieses Flag manchmal auch ohne Benutzeraktivitäten auf true gesetzt wird. Ich vermute, es liegt an der Rundung des Zeitanteils von TDateTime. Es gibt keine anderen Möglichkeiten, wie der Code @ Werte zuweisFCalendarEdit.Date
undFTimeEdit.Time
.
Wie kann ich die in @ gespeicherten Daten richtig vergleicheFCalendarEdit.Date
undFTimeEdit.Time
mit dem in @ gespeicheFDate_Time.FieldValue
?
Angefügt
Das Setzen des Flags auf diese Weise behebt das Problem nicht.
FDate_Time.Modified := (FDate_Time.Modified) or
(DateOf(FDate_Time.FieldValue) <> FCalendarEdit.Date) or
(TimeOf(FDate_Time.FieldValue)<> FTimeEdit.Time);
Appended 2. Auf einen geschätzten Rat von @ Ken-White. Wenn wir die Vergleichszeile durch @ ersetz
FDate_Time.Modified := (FDate_Time.Modified) or
(not SameDateTime(FDate_Time.FieldValue,
FCalendarEdit.Date + FTimeEdit.Time));
Es funktioniert gut. Der TDataTime-Vergleich muss also nur mit dieser Funktion durchgeführt werden.