访问TClientDataSet的TDateField的OldValue时,"0.0"不是有效的时间戳

Fab*_*mes 2 delphi vcl delphi-2009

当我在TClientDataSet中新插入的记录中使用以下代码时:

cdsMyDateField.OldValue <> Null
Run Code Online (Sandbox Code Playgroud)

我得到一个EConvertError:

''0.0' is not a valid timestamp'.
Run Code Online (Sandbox Code Playgroud)

看看Delphi的VCL代码,它试图将值转换为TDateTime,这导致了这个Exception,因为值(Null)是一个无效的DateTime,但是当我比较Variants时我认为它会返回一个变量,这将是Null在这种情况下,但这不会发生,而是我得到这个例外.

我知道我可以在比较值之前检查DataSet.State = dsInsert,就像State = dsInsert每个OldValue都是Null一样,但我想理解为什么OldValue尝试转换值而不是Just all Null in all State = dsInsert时的字段.

任何人都可以给我一些亮点吗?

W.P*_*ins 5

FWIW,我遇到了同样的问题,这让我头疼不已.我的观点:行为是不一致的,所以即使仅仅因为这个原因,我把它归类为一个bug.这也是一个错误,因为在阅读一个属性时提出异常是恕我直言,并且不符合属性的意图(最不惊讶的原则.)我希望OldValue是Unassigned,不会在读取时引发异常.(此外,某些问题已存在很长时间的事实并不意味着它是否是一个错误.)

(编辑:使用更多信息更新我的答案,包括我们的解决方法.也发布到QC报告中:http://qc.embarcadero.com/wc/qcmain.aspx?d = 73852)

我们在一个大量使用datasnap/clientdatasets的应用程序中也遇到了同样的问题.然而,实际问题不在于clientdataset,而是使用SysUtils中的Timestamp验证例程,显然错误地验证了0.0值为无效的Timestamp.

解决方法/修复因此是SysUtils和验证例程,而不是Tclientdataset.具体来说,在验证例程"ValidateTimeStamp()"中,正确比较时间部分<0但错误地比较日期部分<= 0.

因此,(合法的)0.0日期时间值有时会转换为datepart = 0的时间戳,并且当此值再次进行反向验证时(例如,当从此处和QC报告中显示的数据集字段中读取值时), (错误地)提出了一个例外.因此,更改时间戳的Date部分的验证以使用严格小于的简单修复,修复了TClientDataset公开的问题.

这是我们的解决方法,基于Delphi 7.1

(* SysUtils.pas line 10934 (Delphi 7.1)  *)
(**)(* fix - Timestamp values 0.0 erroneously designated as invalid *)
(* D7.1 *)
(* Walter Prins, originally patched May 2005, submitted 4 June 2009 *)
procedure ValidateTimeStamp(const TimeStamp: TTimeStamp);
begin
  if (TimeStamp.Time < 0) or (TimeStamp.Date < 0) then (* Changed TimeStamp.Date <= 0 to TimeStamp.Date < 0 *)
    ConvertErrorFmt(@SInvalidTimeStamp, [TimeStamp.Date, TimeStamp.Time]);
end;
Run Code Online (Sandbox Code Playgroud)