为什么Json.NET DeserializeObject会将时区更改为本地时间?

时间:2012-07-19 04:03:31

标签: c# json.net datetimeoffset

我正在使用json.net反序列化DateTimeOffset,但它忽略了指定的时区并将datetime转换为本地偏移量。例如,给定

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

使用以下代码进行反序列化时

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

obj将包含一个包含DateTimeOffset的属性,但该值将为2012-07-19T15:30:00+10:30,即转换为本地时区而不是保留原始时区。

有没有办法让值按预期进行解析,以便生成的DateTimeOffset属性与提供的值匹配?

8 个答案:

答案 0 :(得分:15)

似乎忽略DateParseHandling.DateTimeOffset并使用DateParseHandling.DateTime。我会在这里记录一个问题:https://github.com/JamesNK/Newtonsoft.Json

答案 1 :(得分:10)

如果您正在使用.NET WebApi,则可以将以下内容添加到WebApiConfig.cs文件中,以便在您的应用程序中全局处理。

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

这将特别告诉JsonFormatter在序列化和反序列化日期时包含并理解本地时区信息。

答案 2 :(得分:9)

尝试使用:

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

我不知道它是否适用于所有情况,但对我而言确实如此。您可以尝试DateTimeZoneHandling的其他值或在Google上搜索更多选项。

答案 3 :(得分:7)

我不确定您使用的是哪个版本,因为在某些时候我们遇到了同样的问题,然后更新修复了它...

你的代码对我来说也错了,但如果我创建类似

的类
public class A
{
    public DateTimeOffset startDateTime;
}

并致电

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

一切都按预期工作。是的,这肯定是错误的,是的,我不知道如何得到你想要的结果,但可能会对其他人有所帮助。

答案 4 :(得分:3)

这对我有用,保留了时区

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,
                });

JSON正文是这样的

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

答案 5 :(得分:0)

要在序列化程序中使用这些设置,请输入:

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

答案 6 :(得分:0)

作为一种简单的方法,您可以将Date转换为Ticks进行序列化,并将其从Ticks转换为Date进行反序列化:

序列化:

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

反序列化”

Datetime = new Datetime(ticks);

答案 7 :(得分:0)

要对自定义Local Date使用正确的JsonConverter,请执行以下操作:

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

我在互联网上进行了艰苦的搜索,将它们结合在一起,最终发现JsonConverter可以被输入JsonSerializerSettings中。