skip to Main Content
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?

enter image description here

That’s

Job Id = POS-1
Employer name = Acme
Start date = 43891
End date = 44355

2

Answers


  1. 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;
    
    Login or Signup to reply.
  2. 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);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search