是否可以为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));