2015-05-22 2 views
6

Рассмотрим следующий код:Почему переменная не может содержать TDateTime до 100 CE?

procedure Test; 
    function d1: Variant; 
    var 
    DDt: TDateTime; 
    begin 
    DDt := EncodeDate(100,1,1); 
    Result := DDt; 
    end; 
    function d2: Variant; 
    var 
    DDt: TDateTime; 
    begin 
    DDt := EncodeDate(99,12,31); 
    Result := DDt; 
    end; 
    procedure Writedate(V: Variant); 
    begin 
    Writeln(string(V)); 
    end; 
var 
    V: Variant; 
begin 
    V := d1; 
    Writedate(V); 
    V := d2; 
    Writedate(V); 
end; 

Первый вызов Writedate преуспеет, и выход будет '01 -01-0100' . Второй вызов, однако, завершится с ошибкой «недопустимый аргумент». При проверке кода вы можете увидеть, что Variant с датой 99-12-31 имеет ошибку EVariantInvalidArgError.

Однако, если я позвоню FormatDateTime('c', TDateTime(V)) на TDateTime, им это удастся. Фактически, в любой момент, когда Variant содержит TDateTime, дата которого предшествует 100 CE, IDE будет отображать EVariantInvalidArgError при проверке его значения.

Кажется странным, что Variant не может справиться с пред-100 CE-датой, когда TDateTime может. Это ошибка в Delphi? Я считаю, что это справа между 99 и 100 CE, чтобы быть немного подозрительным.

ответ

7

Variant может содержать любое значение даты, как показывает ваш код (присвоение V := d2; не вызывает ошибок).

Ошибка возникает при преобразовании в строку, которую компилятор делегирует ОС на платформах Windows. Это не удается, потому что OLE Automation указывает полночь, 1 января 0100, как минимальное допустимое значение даты автоматизации OLE.

+0

Я думал, что Delphi перестала использовать Windows Variants много версий назад. Но варианты все еще полагаются на OLE Automation? – Svip

+2

Весь смысл типа Variant заключается в том, что он является типом interop –

+2

Существует несколько вариантов преобразований, которые делегированы OLE Automation. Вы производите вариант VT_DATE для строки. Это делается путем вызова API 'VarBstrFromDate' в' oleaut32.dll' (см. 'System.Variants' и' System.VarUtils'). Вы можете выполнить код (скомпилированный с помощью debug dcus) и посмотреть сами. –

Смежные вопросы