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

Dar*_*zka 5 delphi delphi-7

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

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

const
   TDateTime_0: TDateTime = 0.0;
Run Code Online (Sandbox Code Playgroud)

这样的作品。然而,我只是继承了一大堆很好的Delphi 7代码,而且我已经好久没有使用Turbo Pascal了......这意味着我真的需要刷我的Delphi fu,这让我想知道。

相比之下,编译器对类似Integer(0). 它分配给一个变体的结果是类型 0 的值ftInteger,而分配一个普通文字 0 将导致一个类型的变体ftSmallInt

澄清:目标是将特定类型的“空”值传递给采用变体的函数(包括编译器管理的变体数组,称为“常量数组”,以及诸如 TParameter.Value 之类的设置器)。

对 Ken White 的澄清:这里的问题本质上是类型推导和重载解析;上面提到的“采用变体的函数”只是一个特例。文字0and0.0可以隐式转换为TDateTime,这就是为什么它们可以分配给该类型的容器(变量、记录字段),并且它们可以用于初始化此类容器(即函数参数),无需多说。但是,当编译器需要进行类型推导时,情况发生了变化:

procedure foo (value: Double); overload; 
procedure foo (value: TDateTime); overload;
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,底层类型都是 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;
Run Code Online (Sandbox Code Playgroud)

我的问题是/只是是否有可能以与上面示例相同的方式形成类型TDateTime(或基于 的其他类型Double)的表达式,而无需为此目的分配和初始化类型化的内存位置。但是,Yuriy 的回答表明这仅适用于序数类型。IntegerTSomeId

Yur*_*kov 3

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

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

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

caption:=DateTimeToStr(0.0); //it shows 30.12.1899
Run Code Online (Sandbox Code Playgroud)

有两个功能可能很方便:

function FloatToDateTime(const Value: Extended): TDateTime; //sysUtils unit
Run Code Online (Sandbox Code Playgroud)

它检查值的边界,如果没问题,则进行单个分配。

function VarFromDateTime(DateTime: TDateTime): Variant;  //Variants unit
Run Code Online (Sandbox Code Playgroud)

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

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

这样的代码可能比使用 TDateTime_0 常量更容易理解,但它有点庞大。