Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi: how to express an empty TDateTime?

Is it possible to express an empty (zero) TDateTime value as a constant? I tried TDateTime(0), TDateTime(0.0) and other things, but the compiler (Delphi 7) wasn't impressed.

At the moment I'm using an initialised global variable:

const
   TDateTime_0: TDateTime = 0.0;

This sort of works. However, I just inherited a nice big pile of Delphi 7 code and I haven't used Turbo Pascal in ages... Which means I seriously need to brush up my Delphi fu, and this makes me want to know.

By contrast, the compiler is perfectly happy with something like Integer(0). Its assignment to a variant results in a value of 0 of type ftInteger, whereas assigning a plain literal 0 would result in a variant of type ftSmallInt.

Clarification: the objective is to pass an 'empty' value of a specific type to functions that take variants (which includes the compiler-managed variant arrays known as 'array of const' and also the setters for things like TParameter.Value).

Clarification for Ken White: the issue here is essentially type deduction and overload resolution; above-mentioned 'functions that take variants' are just a special case. The literals 0 and 0.0 are implicitly convertible to TDateTime, which is why they can be assigned to receptacles of that type (variables, record fields) and they can be used to initialise such receptacles (i.e. function parameters) without further ado. However, things change when the compiler needs to do type deduction:

procedure foo (value: Double); overload; 
procedure foo (value: TDateTime); overload;

The underlying type is Double in both cases, which means that the compiler requires arguments to be typed explicitly (i.e. calls with plain literals are rejected as ambiguous). With ordinal-based types the explicit typing is no problem but type Double is problematic and requires values to be stuffed into typed receptacles before they can be used. Compilable example (requires a Delphi that's a bit newer than Delphi 7):

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;

My question is/was simply whether it is possible to form expressions of type TDateTime (or other types based on Double) in the same way as it is possible for Integer and TSomeId in the example above, without allocating and initialising a typed memory location for that purpose. However, Yuriy's answer indicates that this is only possible for ordinal types.

like image 398
DarthGizka Avatar asked Nov 27 '22 14:11

DarthGizka


1 Answers

Compiler is OK with casting ordinal types to other ordinal types, but refuses to cast floating-point types to each other, even if they are exact the same:

TMyOwnDouble = type double;
...
var a,b: TMyOwnDouble;
...
a:=MyOwnDouble(0.0); //invalid typecast
b:=0.0;  //no problem

What exactly do you want? If this TDateTime constant is needed just to pass it to some function requiring TDateTime, then you can just pass 0.0 and it will work:

caption:=DateTimeToStr(0.0); //it shows 30.12.1899

There are 2 functions which could be handy:

function FloatToDateTime(const Value: Extended): TDateTime; //sysUtils unit

It checks boundaries for Value and if it's all right, makes single assignment.

function VarFromDateTime(DateTime: TDateTime): Variant;  //Variants unit

This one explicitly creates DateTime variant. I tried them both in code like this, they work the same:

var V: Variant;
...
V:=VarFromDateTime(0.0);
//V:=FloatToDateTime(0.0);  //works as well
Caption:=V;  //shows 0:00:00

Code like this may be a little more understandable than using TDateTime_0 constant, but it's a little more bulky.

like image 166
Yuriy Afanasenkov Avatar answered Dec 09 '22 15:12

Yuriy Afanasenkov