2

有没有办法在TDateTime不捕获转换异常的情况下检查 Delphi 变量是否具有有效内容?

我编写了一个应用程序,它必须解析数百个以原始 Delphi 记录形式编写的包含TDateTime字段的巨大文件。有时我会得到一条记录,其中内容的TDateTime值类似于在传递给转换例程时2.0927117954e+262会产生异常。Floating point invalid Operation我知道我可以简单地捕获异常,但这在调试时会很麻烦,因为调试器会不断停止,我想在出现其他错误时保持启用状态。

4

3 回答 3

11

您的示例值显然超出了有效的 DateTime 范围。您可以在执行任何转换之前测试它是否在范围内。

var
  d: TDateTime;
..

d := 2.0927117954e+262;
if (d <= MaxDateTime) and (d >= MinDateTime) then
  s := DateTimeToStr(d)
else
  ..
于 2012-07-31T21:07:14.377 回答
5

如果您的问题是调试器停止,您可以在更高版本的 Delphi 的 IDE 中修复它。在将发生异常的行之前和之后设置两个断点。例如在Delphi 2007中,右键单击第一个BP的边缘红点,选择BreakPoint properties/Advanced/Ignore后续异常。在第二个 BP 上,“处理后续异常”

于 2012-08-01T09:23:08.990 回答
4

阅读您的问题描述,我得出结论,如果某些记录具有损坏/无效的时间值,那么您的应用程序继续读取文件是绝对有效的,因此您希望跳过它(否则可能标记或收集问题)。

VCL 函数System.SysUtils.TryFloatToDateTime正是为此目的而制作的,到目前为止,使用它对我来说似乎是最好的选择。

德尔福示例:

uses SysUtils;

function IsValidDateTime(dt: Double): Boolean;
var
  dummy: TDateTime;
begin
  Result := TryFloatToDateTime(dt, dummy);
end;

C++ 生成器示例:

#include <SysUtils.hpp>

bool isValidDateTime(const double dt) 
{
    TDateTime dummy;
    return TryFloatToDateTime(dt, dummy);
}

这个函数不仅方便(因为没有异常并且已经存在)而且非常易读,它还遵循一个贯穿整个框架的良好约定:

  • 名字开头Try说它可能会失败
  • Boolean直接结果以指示有效操作
  • 间接结果获取实际值(如果操作成功)
于 2014-09-05T09:45:05.433 回答