FWIW, я столкнулся с этой же проблемой, и это вызвало у меня несколько головных болей. Мое мнение: поведение противоречиво, поэтому даже по одной этой причине я классифицирую его как ошибку. Это также ошибка, потому что создание исключения при чтении свойства является ИМХО нелепым и не соответствует назначению свойств (принцип наименьшего удивления). Я бы ожидал, что OldValue будет неназначенным, а не вызовет исключение при чтении. (Кроме того, тот факт, что какая-то проблема существовала в течение длительного времени, не означает, что это ошибка.)
(Изменить: Обновление моего ответа с дополнительной информацией, включая наш обходной путь. Также опубликовано то же самое в отчете QC: http://qc.embarcadero.com/wc/qcmain.aspx?d=73852)
У нас также была такая же проблема в приложении, которое интенсивно использует наборы данных / клиентские наборы данных. Однако настоящая проблема заключается не в наборе данных клиента, а в процедуре проверки метки времени в SysUtils, которая, по-видимому, ошибочно проверяет метку времени со значением 0,0 как недопустимую.
Поэтому обходной путь / исправление относится к SysUtils и подпрограмме проверки, а не к Tclientdataset. В частности, в подпрограмме проверки «ValidateTimeStamp ()» часть времени корректно сравнивается <0, но часть даты ошибочно сравнивается <= 0 . </p>
Следовательно, (допустимое) значение 0.0 Datetime иногда преобразуется в метку времени с 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;