C# 为什么Json.NET反序列化对象会将时区更改为本地时间?

C# 为什么Json.NET反序列化对象会将时区更改为本地时间?,c#,json.net,datetimeoffset,C#,Json.net,Datetimeoffset,我使用json.net反序列化日期时间偏移量,但它忽略指定的时区,并将日期时间转换为本地偏移量。例如,给定 var content = @"{""startDateTime"":""2012-07-19T14:30:00+09:30""}"; 使用以下命令反序列化时: var jsonSerializerSettings = new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.IsoDateFormat,

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

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
属性与提供的值匹配?

它似乎忽略了
DateParseHandling.DateTimeOffset
,并且正在使用
DateParseHandling.DateTime
。我会在这里记录一个问题:

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

你的代码对我来说也是错误的,但是如果我创建一个类似

public class A
{
    public DateTimeOffset startDateTime;
}
打电话

var obj = JsonConvert.DeserializeObject<A>(content, jsonSerializerSettings);
var obj=JsonConvert.DeserializeObject(内容,jsonSerializerSettings);
一切正常。是的,这肯定是一个bug,是的,我不知道如何获得您想要的结果,但可能会对其他人有所帮助。

尝试使用以下方法:

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

我不知道它是否在所有情况下都有效,但对我来说确实有效。您可以尝试使用其他值来处理
DateTimeZoneHandling
或在Google上搜索更多选项。

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

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

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

这对我来说很有效,保留了一个时区

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

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

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

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

DateTime date = new DateTime();
ticks = date.Ticks
序列化:

DateTime date = new DateTime();
ticks = date.Ticks
“反序列化”


要将正确的
本地日期
与自定义
JsonConverter
一起使用,请执行以下操作:

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

我在互联网上努力搜索将它们结合在一起,最终发现
JsonConverter
可以输入
JsonSerializerSettings

有趣的是,日期/时间实际上是正确的,14:30 in+9:30必须是15:30 in+10:30。不确定这里是否有任何关系,但似乎WCF序列化/反序列化确实如此默认情况下也是这样。也许相同的解决方案可以帮助您:我不知道此错误是否已修复。@PeterRitchie是否成功解决此问题?我正在使用8.0.3版本,但仍然得到相同的解决方案issue@JasmeetSingh显示为在Newtonsoft网站上修复。@PeterRitchie是的,我看到了。我的问题是有两个api包装好的。我必须对包装好的进行设置更改。谢谢
var obj = JsonConvert.DeserializeObject(json, type, new JsonSerializerSettings {
    DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
    DateTimeZoneHandling = DateTimeZoneHandling.Local,
    Converters = new JsonConverter[] { new MY_CUSTOM_CONVERTER() }
});