Json.Net triggers time slots for DateTimeOffset on serialization

I've looked at a lot of related questions, but none of them seem to work for me.

I am trying to arrange everything in UTC. Here's my code:

class Class1
{
    static void Main()
    {
        Class2 foo = new Class2();
        JObject json = JObject.Parse(JsonConvert.SerializeObject(foo, new JsonSerializerSettings()
        {
            DateParseHandling = DateParseHandling.DateTimeOffset,
            DateFormatHandling = DateFormatHandling.IsoDateFormat,
            DateTimeZoneHandling = DateTimeZoneHandling.Utc
        }));

        Console.WriteLine(json.ToString());

        Console.Read();
    }
}

class Class2
{
    public DateTimeOffset time = new DateTimeOffset(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(14663484000000000));

    public DateTimeOffset time2 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(14663484000000000);

    public DateTime time3 = new DateTime(14663484000000000);
}

      

Here's the output:

{
    "time": "2016-06-19T08:00:00-07:00",
    "time2": "2016-06-19T08:00:00-07:00",
    "time3": "0047-06-20T15:00:00Z"
}

      

Here's the output I'm trying to get:

{
    "time": "2016-06-19T15:00:00+00:00",
    "time2": "2016-06-19T15:00:00+00:00",
    "time3": "0047-06-20T15:00:00+00:00"
}

      

As you can see, properties DateTimeOffset

are not converted at all. DateTime

is, but the timezone is specified with Z

, whereas I am trying to use +00:00

.

+3


source to share


1 answer


In your code, you do the following:

  • Serialize an instance Class2

    for a JSON string using specific serialization settings DateTime

    .
  • Removing deserialization into the hierarchy JToken

    without using these parameters.
  • (Additional changes to the hierarchy are not shown.)
  • Re-serialize the hierarchy JToken

    to the last line (through json.ToString()

    ) without using these settings.

When you do this, the formatting options for the dates you selected in step 1 will be lost.

To solve this problem, you need to apply the settings every time you serialize a string or to a JSON string representation, since, as described in this documentation page, JSON has no "official" format for dates. Because of this, Json.NET applies heuristics to recognize and format dates whenever it converts from and to a JSON string representation, which you do not once, but three times.

You can accomplish this by running:



var settings = new JsonSerializerSettings()
{
    DateParseHandling = DateParseHandling.DateTimeOffset,
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
    DateTimeZoneHandling = DateTimeZoneHandling.Utc
};

// Generate initial serialization
var initialString = JsonConvert.SerializeObject(foo, settings);

// Parse back to JToken
var json = JsonConvert.DeserializeObject<JObject>(initialString, settings);

// Make modifications as required
// json["foo"] = "bar";

// Generate final JSON.
var finalString = JsonConvert.SerializeObject(json, Formatting.Indented, settings);

      

To be more efficient, you can use JToken.FromObject()

(or JObject.FromObject()

if you like) to generate the hierarchy JToken

without having to create and parse the original string representation:

var settings = new JsonSerializerSettings()
{
    DateParseHandling = DateParseHandling.DateTimeOffset,
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
    DateTimeZoneHandling = DateTimeZoneHandling.Utc
};

var json = JToken.FromObject(foo, JsonSerializer.CreateDefault(settings));

// Make modifications as required
// json["foo"] = "bar";

// Generate final JSON.
var finalString = JsonConvert.SerializeObject(json, Formatting.Indented, settings);

      

Note, however, that Json.NET outputs UTC DateTime

in format "0047-06-20T15:00:00Z"

, not "2016-06-19T15:00:00+00:00"

for the reasons described here here . If you need your UTC DateTime

properties to be serialized in the format DateTimeOffset

, you may need a custom converter .

+5


source







All Articles