Исключение EConvert недопустимая дата и время при попытке преобразовать json в объект с помощью REST.Json

#json #rest #delphi #delphi-10.2-tokyo

#json #rest #delphi #delphi-10.2-токио

Вопрос:

Следующий код попадает в исключение

‘2019.10.5 14:16:14,1000’ не является допустимыми датой и временем

при попытке преобразовать json в объект. Проблема, похоже, в десятичном числе в дате.

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

Если я использую дату с точностью до миллисекунды, которая округляется в меньшую сторону, т.е. "modified": "2019-10-05T14:16:14.4995946Z" она работает нормально.

Я попытался добавить параметры, чтобы установить формат для даты. Order := TJson.JsonToObject<TOrder>(JSonStr, [joDateFormatParse]); . Это предотвращает сбой кода, но дата-время не распознается, и значение заканчивается «0».

В любом случае, или это просто ошибка в библиотеке? Я использую Delphi 10.2 Обновление 3

Комментарии:

1. Это ошибка, которая была исправлена в Delphi 10.3 Rio. См. RSP-16513: ISO8601ToDate округляет дробную часть до 1000 мс и RSP-21840: функция ISO8601ToDate завершается с ошибкой для «2018-11-28T09:16:12.999686Z» .

Ответ №1:

Я создал простую демонстрационную программу с вашим кодом, и она отлично работает с Delphi 10.4.1.

Вот исходный код для демонстрации:

 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.
 

Это ошибка в используемой вами версии Delphi.

Комментарии:

1. Скорее всего, да. Увы, у меня нет подписки на embarcadero, поэтому я не могу ее обновить. Их модель подписки настолько дорогая, что это смешно. В качестве быстрого исправления я объявил FModified как строку. Затем добавлено измененное свойство, которое читает FModified и удаляет все после точки. Я теряю точность, и это далеко не хорошее решение, но на данный момент оно служит цели.