【问题标题】:Delphi: How to determine and empty TDatetime valueDelphi:如何确定和清空 TDatetime 值
【发布时间】:2013-02-20 16:33:29
【问题描述】:

似乎没有办法将 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 值是危险的吗? (作为以前用途的有能力的资源)

【问题讨论】:

  • 如果你打算使用这个函数,我想,NullDate 应该是一个全局常量吗?
  • 在将赋值为零的 TDateTime 变量与 const 值 0 进行比较时遇到了问题。一个 simple if 因为这个没有检查条件 `var v_datetime: TDatetime;` ` v_datetime := 0;` ` if (v_datetime = 0) then actionToTake`
  • 那是因为浮点模糊。使用Math.IsZero
  • 0 是一个完全有效的日期,负日期也很好。 0 是 1899 年 12 月 30 日的午夜。负数是在那之前的日期。

标签: delphi datetime null unassigned-variable


【解决方案1】:

在方法TSession.ExecuteScalar<T> 的库Spring Framework for Delphi 的单元Spring.Persistence.Core.Session.pas 中,如果结果为NULL,则使用值Default(T);

我认为,你的函数可能看起来像

function IsNull(ADate: TDateTime): Boolean;
begin
  Result := ADate = Default(TDateTime);
end;

【讨论】:

    【解决方案2】:

    正如 Andreas 已经写的那样,TDateTime 类型实际上是 double,因此不能“为空”。我用

    const
      c_UnassignedDate = -693594;
    

    对于空日期值,因为这表示不可能的日期 00/00/0000。但是例如 DevExpress 使用

    NullDate = -700000;
    InvalidDate = NullDate + 1;
    

    所以似乎没有一致的标准vale,你应该选择一个适合你需要的。

    【讨论】:

    • 没有 daymonth 为 0(零)的日期。在数据库中,如果日期未分配,则应使用NULL,而不是一些神奇的日期。
    • 是的,对不起。回想一下,我只查看该日期的年份部分......好吧,如果某个日期时间列的值将是 NULL 并且我必须将此值严格存储到 TDateTime 字段中,我可能会使用您的 c_UnassignedDate 常量值。 [+1]
    • 你怎么知道 -693594 代表日期 0/0/0000?
    • @Rob:我猜是因为-693591代表0000-01-03-693592代表0000-01-02-693593代表0000-01-01,至少根据DateTimeToStr
    • @RobKennedy 只需执行ShowMessage(FormatDateTime('dd.mm.yyyy',-693594)); 就会弹出带有00.00.0000 的dlg。
    【解决方案3】:

    首先,您需要定义“空 TDateTime 值”的含义。

    TDateTime 值是一个双精度值,其中日期编码在整数部分,时间编码在小数部分。所以,最接近“空日期”的可能是0

    因此,只需测试 ADate <> 0 即可测试日期是否为“空”。

    但请注意:如果您声明了一个 TDateTime 局部变量,那么在您为其赋值之前,它不一定是 =0。它可以是任何东西。当然,同样的事情也适用于integerdoubleboolean、...类型的变量。

    另外,我相信具有 0 值的 TDateTime 编码日期 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 为“未分配日期”值提供了几个更合理的选择。

    【讨论】:

    • 当日历中断时,负时间日期最终变得毫无意义。
    • @David:好点子。因此,对于“未分配”值,实际上有很多合理的选择。
    • 在这里使用 NaN 作为显式值不会有用吗?然后,您可以使用 IsNaN 来测试条件。
    【解决方案4】:

    tDateTime 对于 0 和 -1 之间的值是未定义的,这意味着 -0.5 的 tDateTime 是未定义的值,并且对于作为 NaN 替代的空日期很有用。 DateTimeToString 将显示 -0.5 与 +0.5 相同;

    【讨论】:

      【解决方案5】:

      使用 PDateTime 代替 TDateTime,并作为 nil 值发送。如果没有指向值的指针,则没有值。

      使用 Assigned ptr 检查值:

      MyDatePointer := nil;
      if ( Assigned(MyDatePointer)) then ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-28
        • 2014-03-06
        • 1970-01-01
        • 1970-01-01
        • 2012-12-03
        • 1970-01-01
        相关资源
        最近更新 更多