如何知道类型变量是Delphi中的DateTime,TO Date和Time

时间:2013-10-03 17:02:09

标签: delphi rtti tdatetime

我需要知道类型变量TDateTime,TDate和TTime。

任何人都知道如何做到这一点?

我使用下面的代码,结果是“不是TDateTime”,“不是TDate”,“不是Ttime”


program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.Rtti,
  System.SysUtils;

var
  DateTime, Date,Time: TValue;

begin

  DateTime:= StrToDateTime( '01/01/2013 01:05:09' );
  if ( DateTime.TypeInfo = System.TypeInfo(TDateTime) ) then
    Writeln( 'Is TDateTime' )
  else
    Writeln( 'Is NOT TDateTime' );

  Date:=  StrToDate( '01/01/2015' );
  if ( Date.TypeInfo = System.TypeInfo(TDate) ) then
    Writeln( 'Is TDate' )
  else
    Writeln( 'Is NOT TDate' );

 Time:=  StrToTime( '01:01:02' );
  if ( Date.TypeInfo = System.TypeInfo(TTime) ) then
    Writeln( 'Is TTime' )
  else
    Writeln( 'Is NOT TTime' );

 Readln;

end.

由于

3 个答案:

答案 0 :(得分:4)

Implicit的{​​{1}}运算符重载让你。

当您将TValueStrToDateTimeStrToDate的结果分配给StrToTime时,它会使用来自{{1}的最匹配的TValue运算符重载} Implicit

另请注意,所有三个函数都返回TValue,因此即使ExtendedTDateTimeTDateTime存在运算符重载,它也无法正常工作。< / p>

要获得正确的结果,您必须在将值分配给TDate变量时明确指定类型:

TTime

答案 1 :(得分:2)

以防您尝试确定StrToDateTime的结果类型:

type
  TDateType = (dtDate, dtDateTime, dtTime);

function getDateType(date: TDateTime): TDateType;
begin
  if Trunc(date) = date then // Or DateOf(date), if available
  begin
    Result := dtDate;
  end
  else
  begin
    if Trunc(date) = 0 then // Or DateOf(date), if avaialble
    begin
      Result := dtTime
    end
    else
    begin
      Result := dtDateTime;
    end;
  end;
end;

// Sample
var
  result: TDateType;
begin
  result := getDateType(StrToDateTime('01/01/2013 01:05:09')); // dtDateTime
  result := getDateType(StrToDateTime('01/01/2015')); // dtDate
  result := getDateType(StrToDateTime('01:01:02')); // dtTime
  // One caveat
  result := getDateType(StrToDateTime('01/01/2013 00:00:00')); // dtDate
end;

或者,您可以使用TryStrToDateTryStrToTimeTryStrToDateTime函数。

答案 2 :(得分:2)

如果你很好奇,TDateTime会在内部编码为浮点Double

TDateTime内部
小数部分表示时间,整数部分表示日期 知道这一点,以下测试将评估为true

dtTime: ABS(Double(DateTime1)) < 1.0 
dtDate: Trunc(Double(DateTime1)) = Double(DateTime1)
dtDateTime:  (     (ABS(Double(DateTime1)) > 1.0) 
         and (Trunc(Double(DateTime1)) <> Double(DateTime1)) )

显然,这是一种非常迂回的测试方式,但有时它有助于了解TDateTime如何在内部塑造。

<强> DateUtils
这些测试的理智版本是:

uses DateUtils;

dtDate: DateTime1 = DateOf(DateTime1)
dtTime: DateTime1 = TimeOf(DateTime1)
dtDateTime:(DateTime1 <> DateOf(DateTime1)) and (DateTime1 <> TimeOf(DateTime1))

TDateTime与Excel兼容
0链接到Microsoft的Excel中的时代:1899年12月30日; 12:00 A.M.
(应该是1-1-1900,但他们改变了它以补偿Lotus'123日期算法中的错误)
这很棒,因为Delphi的TDateTime与Excel的DateTime完全兼容。

以下是官方文档:http://docwiki.embarcadero.com/Libraries/XE5//en/System.TDateTime