0

The following code end up in an exception

'2019.10.5 14:16:14,1000' is not a valid date and time

when trying to parse the json to an object. The problem seems to be the decimal in the date.

  JSonStr := '{"orderNumber": "395409772020_1", "modified": "2019-10-05T14:16:14.9995946Z"}';  
  Order := TJson.JsonToObject<TOrder>(JSonStr);

If I use a date with millisecond precision that rounds downwards i.e "modified": "2019-10-05T14:16:14.4995946Z" it works fine.

I've tried adding options to set the format for the date. Order := TJson.JsonToObject<TOrder>(JSonStr, [joDateFormatParse]);. This prevents the code from crashing, but the DateTime is not recognized and the value ends up with "0".

Anyway around this, or is it simply a bug in the library? I'm running Delphi 10.2 Update 3

Ken White
  • 123,280
  • 14
  • 225
  • 444
Øystein
  • 1,163
  • 1
  • 12
  • 23
  • 5
    It's a bug that was fixed in Delphi 10.3 Rio. See [RSP-16513: ISO8601ToDate rounds fractional part to 1000ms](https://quality.embarcadero.com/browse/RSP-16513) and [RSP-21840: The function ISO8601ToDate fails for "2018-11-28T09:16:12.999686Z"](https://quality.embarcadero.com/browse/RSP-21840). – Peter Wolf Dec 01 '20 at 09:50
  • Embarcadero's website sucks (as always). They ask me to log in order to see those two bugs, but their CAPTCHA is broken. I cannot pass their CAPTCHA. – Gabriel Dec 12 '22 at 16:38

1 Answers1

1

I built a simple demo program with your code and it works perfectly with Delphi 10.4.1.

Here is the source code for the demo:

unit JsonParseDateDemoMain;

interface

uses
    Winapi.Windows, Winapi.Messages,
    System.SysUtils, System.Variants, System.Classes,
    Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
    REST.Json;

type
    TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        procedure Button1Click(Sender: TObject);
    end;

type
    TOrder = class
    private
        FOrderNumber : String;
        FModified    : TDateTime;
    published
        property OrderNumber : String    read  FOrderNumber write FOrderNumber;
        property Modified    : TDateTime read  FModified    write FModified;
    end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
    JsonStr : String;
    Order   : TOrder;
begin
    JsonStr := '{"orderNumber": "395409772020_1", ' +
                '"modified": "2019-10-05T14:16:14.9995946Z"}';
    Order := TJson.JsonToObject<TOrder>(JsonStr);
    Memo1.Lines.Add(Order.OrderNumber);
    Memo1.Lines.Add(DateTimeToStr(Order.Modified));
    Order.Free;
end;

end.

It is a bug in Delphi version you use.

fpiette
  • 11,983
  • 1
  • 24
  • 46
  • 1
    Yes most likely. Alas I do not have a embarcadero subscription so I can not update it. Their subscription model is so expensive its ridiculous. As a quick fix, I've declared FModified as a string. Then added a property Modified that reads FModified and removes everything after the dot. I loose precision and its far from a good solution, but it serves the purpose for now. – Øystein Dec 01 '20 at 14:15
  • I still see this error under 10.4.2 but only when I run the program. If I click the RestRequest at design time, it works. – Gabriel Dec 12 '22 at 16:39