是否可以为DateTimeOffset的JSON.NET反序列化指定偏移量?

以下语句打印“1/1/0001 4:00:00 PM -05:00”

Console.WriteLine(JsonConvert.DeserializeObject("\"0001-01-01T16:00:00\"")); 

这是因为当json.net将DateTime字符串(没有偏移量)反序列化为DateTimeOffset对象时,它会分配本地偏移量,在本例中为-05:00。

如果我不想使用本地偏移怎么办? 有什么方法可以指定用于此反序列化的偏移量吗?

(用例是数据库服务器,Web服务器位于不同的时区,我需要具有区域未指定时间的传入请求,以便在反序列化后使数据库服务器具有偏移量。)

更新:我无法控制传入时间字符串的格式。 我有一个数据传输对象类,它具有DateTimeOffset属性,我需要将传入的时间数据存储到此属性。

您要反序列化的类型应与您期望的数据匹配。 如果您不希望包含偏移量,则不要反序列化为DateTimeOffset 。 而是反序列化为DateTime 。 它的.Kind属性将具有DateTimeKind.Unspecified

您对Web服务器时区的了解与反序列化的任务无关。 因此,事后应用它。

 // deserialize the json DateTime dt = JsonConvert.DeserializeObject("\"2014-01-01T00:00:00\""); // find your target time zone TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); // apply the time zone to determine the offset, and create the DateTimeOffset DateTimeOffset dto = new DateTimeOffset(dt, tz.GetUtcOffset(dt)); 

更新

根据评论,如果您需要以您请求的方式进行此转换,则需要自定义json转换器。 这应该是诀窍:

 public class CustomDateTimeConverter : IsoDateTimeConverter { private readonly string defaultTimeZoneId; public CustomDateTimeConverter(string defaultTimeZoneId) { this.defaultTimeZoneId = defaultTimeZoneId; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (objectType != typeof (DateTimeOffset) && objectType != typeof (DateTimeOffset?)) return base.ReadJson(reader, objectType, existingValue, serializer); var dateText = reader.Value.ToString(); if (objectType == typeof(DateTimeOffset?) && string.IsNullOrEmpty(dateText)) return null; if (dateText.IndexOfAny(new[] { 'Z', 'z', '+'}) == -1 && dateText.Count(c => c == '-') == 2) { var dt = DateTime.Parse(dateText); var tz = TimeZoneInfo.FindSystemTimeZoneById(this.defaultTimeZoneId); var offset = tz.GetUtcOffset(dt); return new DateTimeOffset(dt, offset); } return DateTimeOffset.Parse(dateText); } } 

然后你可以在转换期间连接它:

 var settings = new JsonSerializerSettings(); settings.DateParseHandling = DateParseHandling.None; settings.Converters.Add(new CustomDateTimeConverter(defaultTimeZoneId: "Eastern Standard Time")); DateTimeOffset dto = JsonConvert.DeserializeObject("\"2014-01-01T00:00:00\"", settings); 

请务必使用有效的时区ID。 不要使用固定的偏移量。

此外,如果您尝试通过没有约会的时间,这将不是正确的方法。 这是一个完全不同的问题,并且在0001-01-01传递日期并不是一个好方法。 我很乐意在聊天时和你讨论。

如果原始字符串中的偏移量(-8:00):

 Console.WriteLine(JsonConvert.DeserializeObject("\"0001-01-01T16:00:00-08:00\"")); 

如果没有,试试这个

 var dateTime = JsonConvert.DeserializeObject("\"0001-01-01T16:00:00\""); DateTimeOffset dto = new DateTimeOffset(dateTime, TimeSpan.FromHours(-8));