Got it reproduced in Delphi 2009 update 2 and Delphi 2007 as follows:
uses DB, DBClient;
procedure TTestForm1.TestButtonClick(Sender: TObject);
const
SMyDateField = 'MyDateField';
SMyIntegerField = 'MyIntegerField';
var
MyClientDataSet: TClientDataSet;
MyClientDataSetMyDateField: TField;
MyClientDataSetMyIntegerField: TField;
OldValue: Variant;
begin
MyClientDataSet := TClientDataSet.Create(Self);
MyClientDataSet.FieldDefs.Add(SMyDateField, ftDate);
MyClientDataSet.FieldDefs.Add(SMyIntegerField, ftInteger);
MyClientDataSet.CreateDataSet();
MyClientDataSetMyDateField := MyClientDataSet.FieldByName(SMyDateField);
MyClientDataSetMyIntegerField := MyClientDataSet.FieldByName(SMyIntegerField);
MyClientDataSet.Insert();
OldValue := MyClientDataSetMyIntegerField.OldValue;
OldValue := MyClientDataSetMyDateField.OldValue;
end;
You always get this error:
exception class EConvertError with message ''0.0' is not a valid timestamp'.
I'm not sure if this is to be regarded as a bug:
- upon insert there is technically no OldValue, so obtaining it can raise an exception
- MyClientDataSetMyIntegerField.OldValue returns 0, but MyClientDataSetMyDateField.OldValue raises an exception
Some more notes:
- TCustomClientDataSet.GetFieldData will get the actual underlying data
- TDataSet.DataConvert will convert the underlying data to the native data format, performing validity checks where needed
Edit: as a result of Fabricio's comment I have stressed that OldValue is technically invalid after an insert. So technically this might not be a bug.
His 'new evidence' can be verified by checking the VCL/RTL sources:
For fieldtypes ftDate, ftTime, ftDateTime, TDataSet.DataConvert calls its local NativeToDateTime function which fills a TimeStamp, then converts that using SysUtils.TimeStampToDateTime which in turn calls SysUtils.ValidateTimeStamp which raise an exception when the Time portion is less than zero, or the Date portion is less or equal to zero.
The Date portion can become zero only for fieldtypes ftDate and ftDateTime (TDateField and TDateTimeField), hence only those can raise an exception.
For all other data types, NativeToDateTime will not have problems: those types all allow for a result filled with zero-bytes.
I just checked the RTL/VCL history: since Delphi 6 SysUtils.TimeStampToDateTime calls SysUtils.ValidateTimeStamp, so this behaviour has been the same since 2001.
That makes it really hard to regard this as a bug.