基本问题是您的日期字符串是 Unix 纪元时间 秒 但微软的 JSON 日期格式是 Unix 纪元时间 毫秒,如the documentation 中所述。 Json.NET 自动识别 Microsoft 格式的日期字符串,并在此过程中将偏移量解释为毫秒而不是秒,这解释了为什么 DateTime 显示 1970 年,因为 1970 年是 Unix 纪元的开始年.
您应该修复您的 JSON,以便日期格式与 Microsoft 的格式完全一致,即 "/Date(1485360480000-0800)/"。更好的是,您可以切换到 ISO 8601 format,这是目前首选的日期和时间 JSON 格式。
如果由于某种原因无法更正 JSON 格式,则需要禁用 Json.NET 的自动 DateTime 识别和解析,并创建自己的 custom JsonConverter 继承自 DateTimeConverterBase。
要禁用 Json.NET 的自动日期识别,请在 JsonSerializerSettings 中设置 DateParseHandling = DateParseHandling.None。但是,如果您无法修改整体序列化程序设置,则只能通过将转换器从 Question 40632820 应用于它来禁用包含类型的日期识别,例如:
[JsonConverter(typeof(DateParseHandlingConverter), DateParseHandling.None)] // Disable Json.NET's built-in date time parsing function.
public class RootObject
{
public DateTime pickupBefore { get; set; }
}
接下来,您需要编写自定义的JsonConverter。一种选择是复制 Newtonsoft 的 DateTimeUtils.TryParseDateTime() 和 DateTimeUtils.TryParseDateTimeOffset() 的所有逻辑,在重写 DateTimeUtils.TryParseDateTimeMicrosoft() 和 DateTimeUtils.TryParseDateTimeOffsetMicrosoft() 的过程中以秒而不是毫秒解析纪元数。我开始这样做,但意识到其中涉及相当多的代码 - 超过了 stackoverflow 的答案。作为替代方案,一种快速而简单的技巧是在 JSON 中插入一个额外的 000 子字符串,以将秒数转换为毫秒数,如下所示:
public class MicrosoftSecondsDateTimeConverter : DateTimeConverterBase
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var token = JToken.Load(reader);
if (token.Type == JTokenType.String)
{
var s = ((string)token).Trim();
if (s.StartsWith("/Date(", StringComparison.Ordinal) && s.EndsWith(")/", StringComparison.Ordinal))
{
// MS datetime format is in milliseconds as is shown here:
// https://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_sidebarb
// But our times are offsets in seconds.
// Convert.
var sb = new StringBuilder("\"\\/Date(");
var insert = "000"; // Seconds to MS
for (int i = 6; i < s.Length - 2; i++)
{
if (s[i] == '-' || s[i] == '+') // Time zone marker
{
sb.Append(insert);
insert = string.Empty;
}
sb.Append(s[i]);
}
sb.Append(insert);
sb.Append(")\\/\"");
s = sb.ToString();
var dt = new JsonSerializer().Deserialize(new StringReader(s), objectType);
return dt;
}
}
// Not a Microsoft date.
return new JsonSerializer().Deserialize(token.CreateReader(), objectType);
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
它并不漂亮,但确实可以完成工作。然后将转换器应用于您的类型,如下所示:
[JsonConverter(typeof(DateParseHandlingConverter), DateParseHandling.None)] // Disable Json.NET's built-in date time parsing function.
public class RootObject
{
[JsonConverter(typeof(MicrosoftSecondsDateTimeConverter))]
public DateTime pickupBefore { get; set; }
}
或将其添加到 JsonSerializerSettings.Converters 以更改整个数据模型的 DateTime 字符串的反序列化。
示例fiddle。