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

9

55

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?

Anesthetize answered 19/7, 2012 at 4:3 Comment(3)
Funny thing is that the date/time is actually correct, 14:30 in +9:30 must be 15:30 in +10:30.Brader
Not sure if there's any relation here, but it seems WCF serialization/deserialization does this trick by default as well. Perhaps the same solution could help you: daveonsoftware.blogspot.com/2008/07/…Wills
Hint for other. Sometimes it's better to use DateParseHandling.None to output the date as a string and parse yourself.Oeflein
U
17

It seems to be ignoring DateParseHandling.DateTimeOffset and is using DateParseHandling.DateTime. I would log an issue here: https://github.com/JamesNK/Newtonsoft.Json

Unstop answered 1/8, 2012 at 16:19 Comment(4)
I do not know if this bug has been fixed.Unstop
@PeterRitchie any success resolving this issue? I am using 8.0.3 version but still getting the same issueAplasia
@JasmeetSingh Shows as being fixed on the Newtonsoft site.Unstop
@PeterRitchie yeah I saw that. Problem in my case was there were 2 api's wrapped over one. I had to do the setting changes on the wrapped one. ThanksAplasia
C
16

Try using this:

microsoftDateFormatSettings = new JsonSerializerSettings
{
    DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
    DateTimeZoneHandling = DateTimeZoneHandling.Local
};
var items = JsonConvert.DeserializeObject<List<lstObject>>(jsonString, microsoftDateFormatSettings);

I don't know if it will work in all cases but for me it did. You can try some other values for DateTimeZoneHandling or search for more options on Google.

Croom answered 30/6, 2014 at 3:43 Comment(2)
Not worked - exceptionInearth
Not working , when parsing still recalculate to LocalTime and add local UTC offsetAshbey
C
16

If you're using .NET WebApi you can add the following to the WebApiConfig.cs file to handle this globally in your application.

config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = 
    Newtonsoft.Json.DateTimeZoneHandling.Local;

This will specifically tell the JsonFormatter to include and understand the local time zone information when serializing and deserializing a date.

Cosy answered 28/8, 2015 at 19:14 Comment(0)
E
11

I'm not sure regarding which version did you use, because at some point of time we had the same problem, then update fixed it...

Your code works wrong for me also, but if I create class like

public class A
{
    public DateTimeOffset startDateTime;
}

and call

var obj = JsonConvert.DeserializeObject<A>(content, jsonSerializerSettings);

everything works as expected. Yes, it's bug for sure, yes, I don't know how to get result exactly as YOU want, but probably, it will help for someone else.

Ecclesia answered 17/12, 2012 at 16:1 Comment(0)
K
8

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
    }
]
Kimkimball answered 21/10, 2017 at 8:38 Comment(1)
Confirmed this works perfectly, and I just switched out all my DateTime to DateTimeOffset .NET Core, and works perfectly. This answer should be higher up!Seal
A
2

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.

Appal answered 30/1, 2020 at 8:21 Comment(0)
G
1

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);
Gilbert answered 24/9, 2019 at 14:1 Comment(0)
M
0

To use these settings in serializer, type:

var serializerSettings = new JsonSerializerSettings
            {
                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
                DateTimeZoneHandling = DateTimeZoneHandling.Local
            };
            var serializer = JsonSerializer.Create(serializerSettings);
Marabout answered 25/9, 2018 at 12:59 Comment(0)
B
0

This is the only thing which worked for me (it differs from other supplied answers which didn't work). The key is DateParseHandling.None.

Previously JsonConvert.DeserializeObject was converting UK dates to US dates, even in hyphenated form. e.g. 2023-06-08 to 2023-08-06.

var jsonSerializerSettings = new JsonSerializerSettings
        {
            DateFormatHandling = DateFormatHandling.IsoDateFormat,
            DateTimeZoneHandling = DateTimeZoneHandling.Local,
            DateParseHandling = DateParseHandling.None
        };

then:

JsonConvert.DeserializeObject<*class*>(response.Content.ReadAsStringAsync().Result, jsonSerializerSettings);
Bare answered 8/6, 2023 at 10:29 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.