如何直接在Delphi中执行扩展的JSON $ date,还是System.JSON中有关时区和UTC的错误?

问题描述 投票:0回答:1

我正在尝试使用TJSONObjectBuilder...AddPairs()解析扩展的JSON。我的JSON包含一个$dateMongoDB需要它)。但是无论我如何尝试,时区都会中断。

Input : {"Zulu":{"$date":"2019-01-01T00:00:00.000Z"},"Utc+1":{"$date":"2019-01-01T01:00:00.000+01:00"}}
Output: {"Zulu":{"$date":"2019-01-01T01:00:00.000Z"},"Utc+1":{"$date":"2019-01-01T01:00:00.000Z"}}
                                      ^                                            ^

没有TJsonDateTimeZoneHandling.Utc,它起作用:

Output: {"Zulu":{"$date":"2019-01-01T01:00:00.000+01:00"},"Utc+1":{"$date":"2019-01-01T01:00:00.000+01:00"}}

这是我显示的最小代码:

program SystemJsonDateTest;
{$APPTYPE CONSOLE}
uses
  System.Classes, System.JSON.Types, System.JSON.Writers, System.JSON.Builders;
var
  StringWriter: TStringWriter;
  JsonWriter: TJsonTextWriter;
  Builder: TJSONObjectBuilder;
begin
  StringWriter:= TStringWriter.Create;

  JsonWriter:= TJsonTextWriter.Create(StringWriter);
  JsonWriter.ExtendedJsonMode:= TJsonExtendedJsonMode.StrictMode;
  JsonWriter.DateTimeZoneHandling:= TJsonDateTimeZoneHandling.Utc;

  TJSONObjectBuilder.Create(JsonWriter)
    .BeginObject
      .AddPairs('{"Zulu":{"$date":"2019-01-01T00:00:00.000Z"},"Utc+1":{"$date":"2019-01-01T01:00:00.000+01:00"}}')
    .EndObject
    .Free;

  JsonWriter.Free;
  WriteLn(StringWriter.ToString);
  StringWriter.Free;
  ReadLn;
end.

背景:我正在使用TMongoDocument.AsJSON,发现了此现象,并尝试用最少的代码重现它。如果我做的事情很奇怪或者可以简化,请发表评论...

在那个MongoDocument中,使用了TBsonWriter,但它显示了相同的问题:

Stream:= TFileStream.Create('file.bson', fmCreate);
BsonWriter:= TBsonWriter.Create(Stream);
TJSONObjectBuilder.Create(BsonWriter).BeginObject.AddPairs(//see above
json mongodb delphi utc delphi-10.2-tokyo
1个回答
0
投票

[IIRC MongoDB预期不支持Date字段的“ $ date”扩展语法中的区域。

[reference documentation statesDate值存储为UTC-它们甚至以BSON格式被称为UTC Date,并存储为Int64的Unix毫秒数:

BSON Date是一个64位整数,代表自Unix纪元(1970年1月1日)以来的毫秒数。这导致过去和将来的可表示日期范围约为2.9亿年。

因此,最好只将UTC日期发送到MongoDB,并在客户端进行转换。即使转换正确,在任何情况下您都将丢失区域信息,因为它将存储为UTC。

BTW,最好只在任何类型的数据库中使用UTC日期,然后在显示/报告时使用即时转换为当前用户本地,并将本地区域存储在单独的字段中(如果确实需要) 。

© www.soinside.com 2019 - 2024. All rights reserved.