You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSuperObject解析JSON日期字段异常:字符串日期转数值问题求助

Delphi结合XSuperObject解析JSON日期返回数值而非字符串的解决办法

用Delphi结合XSuperObject组件解析JSON数据时,大部分字段都能正常解析,比如job['Id'].AsString可以正确拿到'POS-1'。但StartDate.Date和EndDate.Date对应的字符串日期(比如'2020-03-01'),用job['StartDate.Date'].AsString获取时,返回的却是43891、44355这类数值,不是原始的字符串日期。

相关代码

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.

程序输出结果

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

问题原因

XSuperObject会自动识别JSON中的日期格式字符串(比如yyyy-mm-dd),并将其转换为Delphi的TDate类型存储——而TDate本质是Double类型,代表从1899年12月30日开始计算的天数。所以调用.AsString时,实际上是把这个浮点数转换成了字符串,而非返回JSON里的原始字符串值。

解决办法

方法1:直接获取原始JSON字符串值

使用.AsJSON属性拿到带引号的原始值,再去掉引号即可:

if Assigned(job['StartDate.Date']) then
  Memo1.Lines.Add('Start date = ' + Trim(job['StartDate.Date'].AsJSON, ['"']));

if Assigned(job['EndDate.Date']) then
  Memo1.Lines.Add('End date = ' + Trim(job['EndDate.Date'].AsJSON, ['"']));

方法2:关闭XSuperObject的自动日期解析

创建ISuperObject时,添加soNoDateParse参数,禁止组件自动识别日期字符串:

job := SO(fileContents, [soNoDateParse]);

之后再调用.AsString就能直接拿到原始的日期字符串了。

方法3:将数值转回日期字符串

如果需要保留日期类型的解析,只是要显示成字符串格式,可以用FormatDateTime把TDate转成指定格式的字符串:

if Assigned(job['StartDate.Date']) then
  Memo1.Lines.Add('Start date = ' + FormatDateTime('yyyy-mm-dd', job['StartDate.Date'].AsTDate));

if Assigned(job['EndDate.Date']) then
  Memo1.Lines.Add('End date = ' + FormatDateTime('yyyy-mm-dd', job['EndDate.Date'].AsTDate));

内容的提问来源于stack exchange,提问作者Mawg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 01:10:29