rpgmaker / NetJSON

Faster than Any Binary? Benchmark: http://theburningmonk.com/2014/08/json-serializers-benchmarks-updated-2/
MIT License
231 stars 29 forks source link

Dictionary<DateTime, Value> or Dictionary<DateTimeOffset, Value> #208

Closed ghost closed 5 years ago

ghost commented 5 years ago

It appears that .ToString() is being called on a dictionary key during serialisation instead of using the NetJSONSettings.DateFormat setting when the key is a date, which results in a loss of precision when deserialising back and comparing values.

I have included two failing tests below, along with the corresponding output format in the comments.

private static readonly NetJSONSettings Settings = new NetJSONSettings { DateFormat = NetJSONDateFormat.ISO, TimeZoneFormat = NetJSONTimeZoneFormat.Utc };

[TestMethod]
public void HandlesDateTimeOffsetDictionaryKey()
{
    var value = DateTimeOffset.UtcNow;
    var s = NetJSON.NetJSON.Serialize(value, Settings); // "2018-11-28T10:41:03.987489Z"
    Assert.AreEqual(value, NetJSON.NetJSON.Deserialize<DateTimeOffset>(s));

    var map = new Dictionary<DateTimeOffset, int> { { value, Random.Next() } };
    var serialised = NetJSON.NetJSON.Serialize(map, Settings); // {"28/11/2018 10:41:29 +00:00":266037427}
    var deserialised = NetJSON.NetJSON.Deserialize<Dictionary<DateTimeOffset, int>>(serialised, Settings);

    Assert.AreEqual(value, deserialised.Keys.Single()); // Fails
    Assert.AreEqual(map[value], deserialised[value]);
}

[TestMethod]
public void HandlesDateTimeDictionaryKey()
{
    var value = DateTime.UtcNow;
    var s = NetJSON.NetJSON.Serialize(value, Settings); // "2018-11-28T10:35:50.9314230Z"
    Assert.AreEqual(value, NetJSON.NetJSON.Deserialize<DateTime>(s));

    var map = new Dictionary<DateTime, int> { { value, Random.Next() } };
    var serialised = NetJSON.NetJSON.Serialize(map, Settings); // {"28/11/2018 10:37:26":871282158}
    var deserialised = NetJSON.NetJSON.Deserialize<Dictionary<DateTime, int>>(serialised, Settings);

    Assert.AreEqual(value, deserialised.Keys.Single()); // Fails
    Assert.AreEqual(map[value], deserialised[value]);
}
rpgmaker commented 5 years ago

Thanks for the find. I will look into it. Thanks

rpgmaker commented 5 years ago

Sorry been busy with other things that came up. I will look at it soon and get back to you.

rpgmaker commented 5 years ago

Please test. Thanks