JamesNK / Newtonsoft.Json

Json.NET is a popular high-performance JSON framework for .NET
https://www.newtonsoft.com/json
MIT License
10.78k stars 3.26k forks source link

JToken vs. JsonConvert discrepancy regarding DateTimeOffset #2000

Open IGx89 opened 5 years ago

IGx89 commented 5 years ago

I've discovered that JsonConvert.DeserializeObject properly interprets the time zone offset on DateTimeOffset fields, but JToken.Parse does not -- it uses the local offset instead. Is this a bug, and if not what's the solution to make JToken.Parse work properly?

Here's a simple repro case -- first test case passes and second test case fails (unless your local offset is -3:00, in which it'll pass)

class TestObject
{
    public DateTimeOffset Time { get; set; }
}

[TestMethod]
public void TestJsonConvert()
{
    var json = @"{ ""time"": ""2019-01-01T12:00:00.0-03:00"" }";

    var dto = JsonConvert.DeserializeObject<TestObject>(json);

    Assert.AreEqual(-3, dto.Time.Offset.Hours);
}

[TestMethod]
public void TestJToken()
{
    var json = JToken.Parse(@"{ ""time"": ""2019-01-01T12:00:00.0-03:00"" }");

    var dto = json.ToObject<TestObject>();

    Assert.AreEqual(-3, dto.Time.Offset.Hours);
}

I need to use JToken.Parse instead of JsonConvert due to needing to extract a version number field from the JSON in order to know which DTO object to deserialize to.

Thanks!

milosloub commented 5 years ago

I have exactly the same issue. The strange is that if I add space between offset and datetime, it's working. Try this line a check result:

JToken.Parse("{ \"date1\":\"2019-05-15T15:00:00+08:00\",\"date2\": \"2019-05-15T15:00:00 +08:00\"}") date1 => 2019-05-15T09:00:00 +02:00 (its calculated to my current offset +02:00 which is wrong) date2 => 2019-05-15T15:00:00 +08:00 (its ok here)

Problem is that it breaks the standard ISO_8601 format with space

Edit: I see that this is global problem described in #862