Как избежать округления данных TDateTime
Я пишу колонки и классы ячеек для FMXTGrid
что будет содержатьTCalendarEdit
а такжеTTimeEdit
экземпляры в каждой клетке. Все работает нормально, кроме правильной обработки изменений, сделанных в этих дочерних элементах управления.
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;
Идея состоит в том, что данные назначаются черезTGrid
OnGetValue
обработчик события. Дата и время отображаются. Пользовательская активность отслеживается иModified
флаг установлен. Проблема в том, что этот флаг иногда устанавливается в true, даже без каких-либо действий пользователя. Я подозреваю, что это связано с округлением временной части TDateTime. Нет других способов, которыми код присваивает значенияFCalendarEdit.Date
а такжеFTimeEdit.Time
.
Как я могу правильно сравнить данные, хранящиеся вFCalendarEdit.Date
а такжеFTimeEdit.Time
с этим хранится вFDate_Time.FieldValue
?
Добавив
Установка флага таким способом не решает проблему.
FDate_Time.Modified := (FDate_Time.Modified) or
(DateOf(FDate_Time.FieldValue) <> FCalendarEdit.Date) or
(TimeOf(FDate_Time.FieldValue)<> FTimeEdit.Time);
Добавлен 2. По ценному совету @ Ken-White. Если мы заменим строку сравнения на
FDate_Time.Modified := (FDate_Time.Modified) or
(not SameDateTime(FDate_Time.FieldValue,
FCalendarEdit.Date + FTimeEdit.Time));
Работает нормально. Поэтому сравнение TDataTime должно выполняться только этой функцией.