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' 只是一个特例。文字 0
和 0.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'
这会将日期设置为空白。
是否可以将空(零)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' 只是一个特例。文字 0
和 0.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' 这会将日期设置为空白。