Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2011-04

Behavior of conversion between vardate variants and string in fpc and delphi

6 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Luiz Americo Pereira Camara

Hi,

As pointed in bug http://bugs.freepascal.org/view.php?id=19075 converting from vardate variants (variants with TDateTime values) to string is done differently in Delphi and fpc. According to http://support.embarcadero.com/article/35913 the conversion is done with the default OS format option independent of shortdatetime.

In the other way (converting from a string variant to a TDateTime) is not allowed at all in Delphi.

Running this code in Delphi 7 gives the exception below:

var
   V: Variant;
   D: TDateTime;
begin
   ShortDateFormat := 'dd/mm/yyyy'; // the problem occurs regardless of
the format option
   V := '20/04/2011';
   D := V;
   Memo1.Lines.Add('Date: ' + DateToStr(D)); // required to avoid dead
code elimination
end;

raised exception class EVariantTypeCastError with message 'Could not convert variant of type (String) into type (Double)'

Can someone check with more recent Delphi if this is still true?

My guess is that Delphi recognizes vardate variants as vardouble so it expects the string compatible with double type. This code works:

var
   V: Variant;
   D: TDateTime;
begin
   V := FloatToStr(Date);
   D := V;
   Memo1.Lines.Add('Date: ' + DateToStr(D));
end;

in fpc:
The same code will do the conversion dependent of the shortdateformat setting, i.e., changing to an incompatible format will raise the exception:

   ShortDateFormat := 'dd/mm/yyyy';
   // Uncomment below to raise an exception  EVariantError : Invalid
variant type cast
   //ShortDateFormat := 'mm/dd/yyyy';
   V := '20/04/2011';
   D := V;
   WriteLn('Date: ' + DateToStr(D));

This has the consequence that, assuming the compatibility fix of my initial patch (that now i see as partially wrong), the following code will not work:

   ShortDateFormat := 'mm/dd/yyyy';
   V := Date;
   S := V;
   V2 := S;

So, what should be done?

1) Be totally compatible with Delphi: convert date to string with hardcoded format and raise exception when doing the conversion back?
2) Use the hardcoded format used to convert from vardate variant to string and vice versa?
3) Use shortdateformat to convert from vardate variant to string and vice versa?

As pointed in http://support.embarcadero.com/article/35913 the hardcoded is not 's the default system setting.

It's a mater of considering where is the Delphi bug. It should use ShortDateFormat to do the vardate to string conversion ? Should the inverse conversion (string to vardate) be allowed at all?

Someone with a more recent Delphi could help to see if one of these bugs were fixed.

Luiz

Reply by email

Sergei Gorelkin
to Luiz Americo Pereira Camara

Luiz Americo Pereira Camara пишет:

Show quoted text 17 lines
So, what should be done? 1) Be totally compatible with Delphi: convert date to string with hardcoded format and raise exception when doing the conversion back? 2) Use the hardcoded format used to convert from vardate variant to string and vice versa? 3) Use shortdateformat to convert from vardate variant to string and vice versa? As pointed in http://support.embarcadero.com/article/35913 the hardcoded is not 's the default system setting. It's a mater of considering where is the Delphi bug. It should use ShortDateFormat to do the vardate to string conversion ? Should the inverse conversion (string to vardate) be allowed at all?

Unfortunately I don't have recent Delphi, but here are results of some quick testing with Delphi 7:

a) Only *assignment* Variant -> TDateTime is broken, explicit casting (e.g. VarAsType(v, varDate)) works.
b) Conversion is done using Windows API (in general, everything Delphi can't or doesn't do itself, it passes on to Windows), having its pros and cons:

test('12 января 2011') -> 12.01.2011 Works, assuming locale is Russian test('04/07/1999') -> 04.07.1999
test('04/17/1999') -> 17.04.1999 Do you really want day and month swapped?

function test(const s: string): string;
var
   v,v1: variant;
   d: tdatetime;
begin
   v := s;
   {d := v;}         // broken
   v1 := VarAsType(v, varDate);
   d := v1;
   result := DateTimeToStr(d);
end;

Regards,
Sergei

Reply by email

LacaK
to Luiz Americo Pereira Camara: As pointed in bug http://bugs.freepascal.org/view.php?id=19075 converting from vardate…
Show quoted text 19 lines
Running this code in Delphi 7 gives the exception below: var V: Variant; D: TDateTime; begin ShortDateFormat := 'dd/mm/yyyy'; // the problem occurs regardless of the format option V := '20/04/2011'; D := V; Memo1.Lines.Add('Date: ' + DateToStr(D)); // required to avoid dead code elimination end; raised exception class EVariantTypeCastError with message 'Could not convert variant of type (String) into type (Double)' Can someone check with more recent Delphi if this is still true?

In DelphiXE:
raised exception class EVariantTypeCastError with message 'Could not convert variant of type (UnicodeString) into type (Double)'

Laco.

Reply by email

LacaK
to Luiz Americo Pereira Camara: As pointed in bug http://bugs.freepascal.org/view.php?id=19075 converting from vardate…
Show quoted text 8 lines
So, what should be done? 1) Be totally compatible with Delphi: convert date to string with hardcoded format and raise exception when doing the conversion back? 2) Use the hardcoded format used to convert from vardate variant to string and vice versa? 3) Use shortdateformat to convert from vardate variant to string and vice versa?

Point 3 sounds to me as best and logical.

This code in DelphiXE:

   ShortDateFormat := 'dd#mm#yyyy'; // the problem occurs regardless of
the format option
   DateSeparator:='#';
   V := '20#04#2011';
   v1:=varAsType(V, varDate);
   D:=v1;
   Writeln('Date: ' + DateToStr(D));

Outputs:
Date: 20#04#2011

So it seems, that DelphiXe also uses ShortDateFormat, DateSeparator

Laco.

Reply by email

Luiz Americo Pereira Camara
to Sergei Gorelkin: Luiz Americo Pereira Camara пишет: Unfortunately I don't have recent Delphi, but…
Sergei Gorelkin wrote 10 lines
Unfortunately I don't have recent Delphi, but here are results of some quick testing with Delphi 7: a) Only *assignment* Variant -> TDateTime is broken, explicit casting (e.g. VarAsType(v, varDate)) works. b) Conversion is done using Windows API (in general, everything Delphi can't or doesn't do itself, it passes on to Windows), having its pros and cons:

Thanks for your test

Since the use of the os api would need system dependent code i'm in favor of using the shordateformat.

Luiz

Reply by email

Luiz Americo Pereira Camara
to LacaK: Point 3 sounds to me as best and logical. This code in DelphiXE: ShortDateFormat :=…
LacaK wrote 11 lines
> So, what should be done? > > 1) Be totally compatible with Delphi: convert date to string with > hardcoded format and raise exception when doing the conversion back? > 2) Use the hardcoded format used to convert from vardate variant to > string and vice versa? > 3) Use shortdateformat to convert from vardate variant to string and > vice versa? Point 3 sounds to me as best and logical.

Agree. my second patch does that

Luiz

Reply by email