gpt4 book ai didi

JSON.Net BSON 序列化不正确地处理 DateTimeOffset?

转载 作者:行者123 更新时间:2023-12-04 02:12:30 29 4
gpt4 key购买 nike

我正在尝试使用 JSON.Net 序列化为 BSON,但原始偏移量似乎没有得到遵守。

你能看出我如何努力使这项工作有问题吗?

[Test]
public void SerializeDateTimeOffsetToBson()
{
var serializer = new Newtonsoft.Json.JsonSerializer {
TypeNameHandling = TypeNameHandling.Auto,
DateParseHandling = DateParseHandling.DateTimeOffset,
DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind
};

var negOffset = new DateTimeOffset(2014, 7, 10, 0, 0, 0, new TimeSpan(-5, 0, 0));
var gmtOffset = new DateTimeOffset(2014, 7, 10, 0, 0, 0, new TimeSpan());
var posOffset = new DateTimeOffset(2014, 7, 10, 0, 0, 0, new TimeSpan(5, 0, 0));

var dt = new {
negOffset = negOffset,
gmtOffset = gmtOffset,
posOffset = posOffset
};

byte[] serialized;

using (var ms = new MemoryStream())
using (var writer = new BsonWriter(ms)) {
serializer.Serialize(writer, dt);
writer.Close();
serialized = ms.ToArray();
}

dynamic deserializedDt;

using (var ms = new MemoryStream(serialized))
using (var rdr = new BsonReader(ms)) {
deserializedDt = (dynamic)serializer.Deserialize(rdr);
rdr.Close();
}

Assert.IsTrue(deserializedDt.negOffset == dt.negOffset);
Assert.IsTrue(deserializedDt.posOffset == dt.posOffset);
Assert.IsTrue(deserializedDt.gmtOffset == dt.gmtOffset);
}

所有三个断言都会失败。

反序列化后,deserializedDt.negOffset 为 2014 年 7 月 9 日晚上 10 点,偏移量为 -07:00(计算机当前时区),deserializedDt.posOffset 为 7 月 9 日2014 年中午 12 点,偏移量为 -07:00,deserializedDt.gmtOffset 为 2014 年 7 月 9 日下午 5 点,偏移量为 -07:00。

在 .Net 4.0 项目中使用 JSON.Net 8.0.3。

更新--------------------

经过进一步调查,我在 Github 上提出了一个关于此的问题 https://github.com/JamesNK/Newtonsoft.Json/issues/898

最佳答案

BSON 规范不允许存储 DateTime 的偏移量; it stores UTC datetime as an Int64 , 自 Unix 纪元以来的毫秒数。

如果您不想丢失偏移量,您可以创建一个 JsonConverter,它将 DateTime 与偏移量分开,以分别序列化(和反序列化)两者。例如:

public class DateTimeOffsetConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(DateTimeOffset) == objectType;
}

public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
Newtonsoft.Json.JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.StartObject)
return null;

reader.Read(); // PropertyName "DateTimeInTicks"
reader.Read(); // Property value
var ticks = (Int64)reader.Value;

reader.Read(); // PropertyName "Offset"
reader.Read(); // Property value
var offset = TimeSpan.Parse((String)reader.Value);

// Move forward to JsonToken.EndObject
reader.Read();

return new DateTimeOffset(ticks, offset);
}

public override void WriteJson(
JsonWriter writer,
object value,
Newtonsoft.Json.JsonSerializer serializer)
{
var dateTimeOffset = (DateTimeOffset)value;

var toSerialize = new {
DateTimeInTicks = dateTimeOffset.DateTime.Ticks,
Offset = dateTimeOffset.Offset
};

serializer.Serialize(writer, toSerialize);
}
}

然后您可以将它应用到您的类中,如下所示:

public class TestClass
{
public Int32 TestInt { get; set; }

[JsonConverter(typeof(DateTimeOffsetConverter))]
public DateTimeOffset TestDateTimeOffset { get; set; }

public String TestString { get; set; }

[JsonConverter(typeof(DateTimeOffsetConverter))]
public DateTimeOffset? TestNullableDateTimeOffset { get; set; }
}

关于JSON.Net BSON 序列化不正确地处理 DateTimeOffset?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36944671/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com