Why does Json.NET DeserializeObject change the timezone to local time?

Viewed 56027

I'm using json.net to deserialize a DateTimeOffset, but it is ignoring the specified timezone and converting the datetime to the local offset. For example, given

var content = @"{""startDateTime"":""2012-07-19T14:30:00+09:30""}";

When deserialised using:

var jsonSerializerSettings = new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.IsoDateFormat, DateParseHandling = DateParseHandling.DateTimeOffset, DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind };
var obj = JsonConvert.DeserializeObject(content, jsonSerializerSettings);

The obj will contain a property containing a DateTimeOffset but the value will be 2012-07-19T15:30:00+10:30 i.e. converted to the local timezone instead of preserving the original timezone.

Is there a way to get the value to be parsed as expected so that the resulting DateTimeOffset property will match the supplied value?

8 Answers

This works for me, a timezone is preserved

var jss = new JsonSerializerSettings
    {
         DateFormatHandling = DateFormatHandling.IsoDateFormat,
         DateTimeZoneHandling = DateTimeZoneHandling.Local, 
         DateParseHandling = DateParseHandling.DateTimeOffset
    };
var responseObj = JsonConvert.DeserializeObject<dynamic>(body, jss);
return responseObj.Select(s => new {
                    id = s["id"].Value<int>(),
                    date = s["date"].Value<DateTimeOffset>().DateTime,
                });

A JSON body is something like this

[
    {
        "id": 211,
        "date": "2017-10-22T12:00:00+03:00",
        "status": 1
    },
    {
        "id": 212,
        "date": "2017-10-28T12:00:00+03:00",
        "status": 1
    }
]

To use the correct Local Date with custom JsonConverter, do:

var obj = JsonConvert.DeserializeObject(json, type, new JsonSerializerSettings {
    DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
    DateTimeZoneHandling = DateTimeZoneHandling.Local,
    Converters = new JsonConverter[] { new MY_CUSTOM_CONVERTER() }
});

I search hard on the internet to combine them together, and eventually found JsonConverter can be feed into JsonSerializerSettings.

To use these settings in serializer, type:

var serializerSettings = new JsonSerializerSettings
            {
                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
                DateTimeZoneHandling = DateTimeZoneHandling.Local
            };
            var serializer = JsonSerializer.Create(serializerSettings);

As a simple way, you can Convert Date to Ticks for serializing and convert it from Ticks to Date for deserializing:

Serializing:

DateTime date = new DateTime();
ticks = date.Ticks

Deserializing"

Datetime = new Datetime(ticks);
Related