Delphi: 如何表达一个空的TDateTime?

Delphi: how to express an empty TDateTime?

是否可以将空(零)TDateTime 值表示为常量?我尝试了 TDateTime(0)TDateTime(0.0) 和其他东西,但编译器 (Delphi 7) 没有留下深刻印象。

目前我正在使用初始化的全局变量:

const
   TDateTime_0: TDateTime = 0.0;

这类作品。然而,我刚刚继承了一大堆 Delphi 7 代码,而且我已经很久没有使用 Turbo Pascal 了……这意味着我真的需要重温我的 Delphi fu,这让我想知道。

相比之下,编译器对 Integer(0) 这样的东西非常满意。它分配给变体会导致类型为 ftInteger 的值 0,而分配普通文字 0 会导致类型为 ftSmallInt.

的变体

澄清:objective 是将特定类型的 'empty' 值传递给采用变体的函数(其中包括编译器管理的变体数组 'array of const' 以及TParameter.Value).

之类的设置器

Ken White 的澄清:这里的问题本质上是类型推导和重载解析;上面提到的 'functions that take variants' 只是一个特例。文字 00.0 可以隐式转换为 TDateTime,这就是为什么可以将它们分配给该类型的容器(变量、记录字段)并且它们可以用于初始化此类容器的原因(即函数参数)事不宜迟。但是,当编译器需要进行类型推导时,情况就会发生变化:

procedure foo (value: Double); overload; 
procedure foo (value: TDateTime); overload;

在这两种情况下,基础类型都是 Double,这意味着编译器需要显式键入参数(即,使用纯文字的调用会因不明确而被拒绝)。对于基于序数的类型,显式类型没有问题,但类型 Double 是有问题的,并且需要在使用之前将值填充到类型化容器中。可编译示例(需要比 Delphi 7 更新一点的 Delphi):

type
   TSomeId = type Integer;

procedure foo (value: Integer  ); overload;  begin  WriteLn('Integer   ', value);  end;
procedure foo (value: TSomeId  ); overload;  begin  WriteLn('TSomeId   ', value);  end;
procedure foo (value: Double   ); overload;  begin  WriteLn('Double    ', value);  end;
procedure foo (value: TDateTime); overload;  begin  WriteLn('TDateTime ', value);  end;

procedure test_TYPE_Double;
var
   d: Double;
   t: TDateTime;
begin
   foo(Integer(0));
   foo(TSomeId(0));
   d := 0;  foo(d);
   t := 0;  foo(t);
end;

我的问题 is/was 是否可以像 TDateTime 类型(或基于 Double 的其他类型)的表达式一样构造表达式24=] 和 TSomeId 在上面的例子中,没有为此目的分配和初始化类型化的内存位置。但是,Yuriy 的回答表明这仅适用于序数类型。

编译器可以将序数类型转换为其他序数类型,但拒绝将浮点类型相互转换,即使它们完全相同:

TMyOwnDouble = type double;
...
var a,b: TMyOwnDouble;
...
a:=MyOwnDouble(0.0); //invalid typecast
b:=0.0;  //no problem

你到底想要什么?如果需要这个 TDateTime 常量只是为了将它传递给需要 TDateTime 的某个函数,那么您只需传递 0.0 即可:

caption:=DateTimeToStr(0.0); //it shows 30.12.1899

有 2 个函数可以派上用场:

function FloatToDateTime(const Value: Extended): TDateTime; //sysUtils unit

它检查 Value 的边界,如果一切正常,则进行单一赋值。

function VarFromDateTime(DateTime: TDateTime): Variant;  //Variants unit

这个显式创建 DateTime 变体。 我在这样的代码中尝试了它们,它们的工作原理相同:

var V: Variant;
...
V:=VarFromDateTime(0.0);
//V:=FloatToDateTime(0.0);  //works as well
Caption:=V;  //shows 0:00:00

这样的代码可能比使用 TDateTime_0 常量更容易理解,但体积更大。

将日期设置为 'gg' 这会将日期设置为空白。