似乎无法将 NULL(或“未分配值”)分配给
TDateTime
变量。
我想象的唯一方法是使用这样的东西:
function isNull(aDate : TDateTime) : boolean;
const NullDate = 0.0;
var aNullDate : TDatetime;
ms : Int64;
begin
aNullDate := NullDate;
ms := MilliSecondsBetween(aDate,aNullDate);
result := (ms = Int64(0));
end;
有人知道不与 0 日期值重叠的更好解决方案吗?
负
TDateTime
值危险吗? (我的意思是,作为用于上述目的的可用资源)
TDateTime
类型实际上是 double
,因此不可“为空”。我用
const
c_UnassignedDate = -693594;
对于空日期值,因为这代表不可能的日期
00/00/0000
。但例如 DevExpress 使用
NullDate = -700000;
InvalidDate = NullDate + 1;
所以似乎没有一致同意的标准值,您应该选择一个适合您需要的。
首先您需要定义“空
TDateTime
值”的含义。
A
TDateTime
值是一个双精度值,其中整数部分编码为日期,小数部分编码为时间。因此,您可以获得的最接近“空日期”的可能是 0
。
因此,只需测试
ADate <> 0
即可测试日期是否为“空”。
但要注意:如果你声明了一个
TDateTime
局部变量,那么在给它赋值之前它不一定是 =0
。它可以是任何东西。当然,同样的情况也适用于 integer
、double
、boolean
、... 类型的变量
此外,我相信具有值
TDateTime
的 0
编码日期 1899-12-30。
最后,负
TDateTime
值是完全正常的。例如,-5000
对应于1886-04-22
。
我不太明白你的代码的意义。如果您想使用
0
作为“未分配”值(如果您对接近 1899-12-30 的日期感兴趣,这很糟糕),为什么不简单地做
function IsUnassigned(ADate: TDateTime): boolean;
begin
result := ADate = 0;
end;
或者,可能(但不等同!),
function IsUnassigned(ADate: TDateTime): boolean;
begin
result := IsZero(Date);
end;
在他的回答中,ain 为“未分配日期”值给出了一些更合理的选择。
在库
Spring Framework for Delphi(http://www.spring4d.org) 的单元
Spring.Persistence.Core.Session.pas
中的方法 TSession.ExecuteScalar<T>
如果结果使用值 Default(T);
为 NULL
我想,你的函数可以是这样的
function IsNull(ADate: TDateTime): Boolean;
begin
Result := ADate = Default(TDateTime);
end;
使用 PDateTime 代替 TDateTime,并以 nil 值发送。如果没有指向值的指针,则结果没有值。
要检查值,请使用分配的 ptr :
MyDatePointer := nil;
if ( Assigned(MyDatePointer)) then ...
TDateTime 对于 0 到 -1 之间的值是未定义的,这意味着 -0.5 的 tDateTime 是一个未定义的值,对于空日期作为 NaN 的替代非常有用。 DateTimeToString 将显示 -0.5,与 +0.5 相同;
System.TDateTime
的文档中所述,
TDateTime 值的整数部分是自 1899 年 12 月 30 日以来经过的天数。TDateTime 值的小数部分是一天中的时间。 […]
TDateTime 也支持负值。您应该谨慎使用负 TDateTime 值。错误使用负值会导致各种问题。
允许负值,但必须小心处理:
使用负 TDateTime 值时,计算必须单独处理时间部分。小数部分反映一天 24 小时的分数,而不考虑 TDateTime 值的符号。例如,上午 6:00 1899 年 12 月 29 日的值为 –1.25,而不是 –1 + 0.25,后者等于 –0.75。大于 -1.0 到 0.0 的日期和小于 1.0 到 0.0 的日期相互镜像。那是因为 +ve 零 和 -ve 零 相等。
到目前为止,似乎可以在代码中使用
-0.5
作为 NULL 替换。
因此,将
TDateTime
视为正常 Double
值通常不是一个好主意。一旦您的计算跨越“Delphi 纪元”(1899-12-30 00:00:00)的开始,如果不仅仅是日期(日粒度),即编码为 Integer
的 Double
值,结果就会出现偏差。 .
我认为这可能是一个很好的起点:
const
NULL_DATE_TIME = TDateTime(-0.5);
function IsNullDateTime(Value: TDateTime): Boolean;
begin
Result := Value = NULL_DATE_TIME;
end;
我在这里的双重比较中故意不使用 epsilon,因为 -0.5 完美地以 IEEE-754 格式表示,并且正常的
TDateTime
值永远不应该达到 -1 和 0 之间的区间(不包含)。
但是,我不太确定我的最后一个断言:我手头只有过时的 C++Builder 6,并且
IncDay(TDateTime(0.5),-1)
不幸的是返回了这个值。我希望这个错误现在已经修复了。
我现在测试的是当前的Lazarus版本没有出现这个bug。