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

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 aDouble. You are seeing XSuperObject parsing your JSON'sStartDateandEndDatefields as if they wereTDatevalues, not plainStringvalues. And then, when you call.AsStringon those fields, you are getting back the numeric representation of thoseTDatevalues, not the originalStringdata.You can disable this behavior, however the
SO()function does not allow you to do so. You will have to construct aTSuperObjectobject directly, so you can passFalseto itsCheckDateparameter (which isTrueby default), eg: