asd*_*-tm 2 delphi datetime firemonkey
我写FMX柱和小区类别TGrid将包含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;
Run Code Online (Sandbox Code Playgroud)
想法是通过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);
Run Code Online (Sandbox Code Playgroud)
附加2.关于@Ken-White的重要建议.如果我们替换比较线
FDate_Time.Modified := (FDate_Time.Modified) or
(not SameDateTime(FDate_Time.FieldValue,
FCalendarEdit.Date + FTimeEdit.Time));
Run Code Online (Sandbox Code Playgroud)
它工作正常.因此,TDataTime比较必须仅由此函数完成.
TDateTime是的type Double,这意味着它是一个浮点值,因此这样做的相等比较时没有指定的可接受的增量(差)是受二进制表示的通常问题..
特别是对于TDateTime值,您可以使用DateUtils.SameDateTime将等式比较到小于1毫秒:
FDate_Time.Modified := (FDate_Time.Modified) or
(not SameDateTime(FDate_Time.FieldValue,
FCalendarEdit.Date + FTimeEdit.Time));
Run Code Online (Sandbox Code Playgroud)