unit fmainForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses XSuperObject;
procedure TForm1.FormCreate(Sender: TObject);
var fileContents : string;
job: ISuperObject;
LDate: TDate;
LValue: string;
LFormat: TFormatSettings;
LDouble: Double;
begin
fileContents := '{'
' "Id": "POS-1",'
' "Employer": {'
' "Name": {'
' "Normalized": "Acme"'
' }'
' },'
' "IsSelfEmployed": false,'
' "IsCurrent": true,'
' "StartDate": {'
' "Date": "2020-03-01",'
' },'
' "EndDate": {'
' "Date": "2021-06-08",'
' },'
'}';
job := SO(fileContents);
if Assigned(job['Id']) then
Memo1.Lines.Add('Job Id = ' job['Id'].AsString);
if Assigned(job['Employer.Name.Normalized']) then
Memo1.Lines.Add('Employer name = ' job['Employer.Name.Normalized'].AsString);
if Assigned(job['StartDate.Date']) then
Memo1.Lines.Add('Start date = ' job['StartDate.Date'].AsString);
if Assigned(job['EndDate.Date']) then
Memo1.Lines.Add('End date = ' job['EndDate.Date'].AsString);
end;
end.
Most of it works. E.g job['Id'].AsString
evaluates to 'POS-10'
, etc.
But job['StartDate.Date'].AsString
evaluates to '43891'
and EndDate to '44355'
. What am I doing wrong?
That's
Job Id = POS-1
Employer name = Acme
Start date = 43891
End date = 44355
CodePudding user response:
Looking at XSuperObject's source code, it turns out that by default, XSuperObject will process a String field as a Date/Time field if the string value resembles a valid date/time string (which it does, in this situation).
In Delphi, a TDate(Time)
is implemented as a Double
. You are seeing XSuperObject parsing your JSON's StartDate
and EndDate
fields as if they were TDate
values, not plain String
values. And then, when you call .AsString
on those fields, you are getting back the numeric representation of those TDate
values, not the original String
data.
You can disable this behavior, however the SO()
function does not allow you to do so. You will have to construct a TSuperObject
object directly, so you can pass False
to its CheckDate
parameter (which is True
by default), eg:
//job := SO(fileContents);
job := TSuperObject.Create(fileContents, False);
CodePudding user response:
TDate
is just a normal Double
type.
When you do AsString
, in reality you convert the double value as string.
You will see that your field contain a TDate and not a string by doing :
LType := job['StartDate.Date'].DataType; // dtDate
If you want to get the date value as string, you need to use DateToStr
:
if Assigned(job['StartDate.Date']) and (job['StartDate.Date'].DataType = dtDate) then
begin
Memo1.Lines.Add('Start date = ' DateToStr(job['StartDate.Date'].AsDate));
end;