如何使用Newtonsoft.Json反序列化带$date字段的EPOCH格式时间数据
问题原因
你使用的DateFormatHandling.MicrosoftDateFormat仅适配\/Date(毫秒级时间戳)\/格式的字符串时间戳,无法识别{"$date": 时间戳}这种嵌套对象结构的时间格式,反序列化时预期读取时间字符串却遇到了{开头的对象,和你定义的DateTime类型属性不匹配,因此抛出该报错。
解决方案1:自定义JsonConverter(推荐)
这种方式无需改动原有Model的属性类型,可全局适配该格式的时间解析:
- 实现自定义转换器类
using Newtonsoft.Json; using Newtonsoft.Json.Linq; public class EpochNestedDateConverter : JsonConverter<DateTime> { public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer) { JObject dateObj = JObject.Load(reader); long epochMs = dateObj["$date"].Value<long>(); // 按需返回UTC时间或本地时间,当前返回本地时间 return DateTimeOffset.FromUnixTimeMilliseconds(epochMs).LocalDateTime; } public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer) { // 若不需要序列化回该格式可直接抛出NotImplementedException writer.WriteStartObject(); writer.WritePropertyName("$date"); writer.WriteValue(new DateTimeOffset(value).ToUnixTimeMilliseconds()); writer.WriteEndObject(); } }
- 把转换器添加到反序列化配置中
var settings = new JsonSerializerSettings { Converters = new List<JsonConverter> { new EpochNestedDateConverter() } }; Data = JsonConvert.DeserializeObject<Constructores_IdPnODH.Data>(payload_Decryp, settings);
如果只需要单个属性适配该格式,不需要全局配置,也可以直接在Model对应的fechaGrabacionODH属性上添加特性:
[JsonConverter(typeof(EpochNestedDateConverter))] public DateTime fechaGrabacionODH { get; set; }
解决方案2:新增嵌套类适配结构
不想自定义转换器的话,可以直接改动Model适配JSON结构:
// 新增嵌套类 public class NestedEpochDate { [JsonProperty("$date")] public long Timestamp { get; set; } // 扩展属性直接返回转换后的时间 public DateTime DateTimeValue => DateTimeOffset.FromUnixTimeMilliseconds(Timestamp).LocalDateTime; } // 修改原有Data类中的属性类型 public class Data { // 其他属性省略 public NestedEpochDate fechaGrabacionODH { get; set; } }
后续使用时访问fechaGrabacionODH.DateTimeValue即可获取转换后的时间。
内容的提问来源于stack exchange,提问作者Arlunily
相关产品推荐
相关产品推荐

