Consider the following code:
procedure Test;
function d1: Variant;
var
DDt: TDateTime;
begin
DDt := EncodeDate(100,1,1);
Result := DDt;
end;
function d2: Variant;
var
DDt: TDateTime;
begin
DDt := EncodeDate(99,12,31);
Result := DDt;
end;
procedure Writedate(V: Variant);
begin
Writeln(string(V));
end;
var
V: Variant;
begin
V := d1;
Writedate(V);
V := d2;
Writedate(V);
end;
The first call to Writedate
will succeed, and the output will be '01-01-0100'. The second call, however, will fail with an 'invalid argument' failure. Inspecting the code, you can see the Variant
of the 99-12-31 date has a EVariantInvalidArgError
error.
However, if I call FormatDateTime('c', TDateTime(V))
on either TDateTime
, they will both succeed. In fact, at any point when the Variant
contains a TDateTime
, whose date is before 100 CE, the IDE will display a EVariantInvalidArgError
when inspecting its value.
It seems odd that the Variant
cannot handle the pre-100 CE date, when TDateTime
can. Is this a bug in Delphi? I find it being right between 99 and 100 CE to be a bit suspicious.
Assigning a Variant to a TDateTime variable does not work. Because TDateTime is a floating-point type, the assignment would try to convert the Variant to a varDouble, not a varDate.
Because TDateTime is a floating-point type, the assignment would try to convert the Variant to a varDouble, not a varDate. VarToDateTime eventually calls the Windows API function VariantChangeTypeEx to parse the string and interpret the date and time. See the Platform SDK documentation for details.
You can assess the value by using std::get, std::get_if or by using a form of a visitor. To check the currently active type you can use std::holds_alternative or std::variant::index std::visit is a way to invoke an operation on the currently active type in the variant.
There are several ways you can create and initialize std::variant: Play with the code here @Coliru. if that’s not possible when the type doesn’t have a default constructor, then you’ll get a compiler error you can use std::monostate to pass it as the first type in that case
Variant
can contain any date value, as your code demonstrates (assignment V := d2;
produces no error).
The error is raised during the conversion to string which the compiler delegates to the OS on Windows platforms. This fails because OLE Automation specifies midnight, 1 January 0100 as the minimum valid OLE Automation date value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With