如何使用JSON.Net转换新的日期(年,月,日)重载

我正在尝试解析日期定义为JavaScript对象的 JSON文件:

new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]); 

所以我尝试用JavaScriptDateTimeConverter解析它

test.json:

 {"data" : [{"Date" : new Date(2015, 06, 01, 00, 00, 00)}]} 

C#:

 using (StreamReader file = File.OpenText(@"c:\test.json")) { JsonSerializer serializer = new JsonSerializer(); serializer.Converters.Add(new JavaScriptDateTimeConverter()); Rootobject deserializedRoot = (Rootobject)serializer.Deserialize(file, typeof(Rootobject)); } 

不幸的是我收到了这个错误:

意外的令牌解析日期。 期待的EndConstructor,得到了Integer。 路径’数据[0]。日期1 ‘,第13行,第30位。

根据我的理解,JSON.Net充其量只需要一个new Date(52231943)但不处理Javascript Date()对象的构造函数重载。

是否有任何已知的方法来转换new Date(year, month, day)

您可以像这样创建自己的JavaScriptDateTimeConverter.cs子类:

 public class JavaScriptYMDDateTimeConverter : JavaScriptDateTimeConverter { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { Type type = (Nullable.GetUnderlyingType(objectType) ?? objectType); bool isNullable = (Nullable.GetUnderlyingType(objectType) != null); var token = JToken.Load(reader); if (token == null || token.Type == JTokenType.Null) { if (!isNullable) throw new JsonSerializationException(string.Format("Null value for type {0} at path {1}", objectType.Name, reader.Path)); return null; } if (token.Type != JTokenType.Constructor) { throw new JsonSerializationException(string.Format("Invalid Date constructor \"{0}\" at path {1}", token.ToString(), reader.Path)); } var constructor = (JConstructor)token; if (!string.Equals(constructor.Name, "Date", StringComparison.Ordinal)) { throw new JsonSerializationException(string.Format("Invalid Date constructor \"{0}\" at path {1}", token.ToString(), reader.Path)); } var values = constructor.Values().ToArray(); if (values.Length == 0) { throw new JsonSerializationException(string.Format("Invalid Date constructor \"{0}\" at path {1}", token.ToString(), reader.Path)); } else if (values.Length == 1) { // Assume ticks using (var subReader = constructor.CreateReader()) { while (subReader.TokenType != JsonToken.StartConstructor) subReader.Read(); return base.ReadJson(subReader, objectType, existingValue, serializer); // Use base class to convert } } else { var year = (values.Length > 0 ? (int)values[0] : 0); var month = (values.Length > 1 ? (int)values[1] : 0) + 1; // c# months go from 1 to 12, JavaScript from 0 to 11 var day = (values.Length > 2 ? (int)values[2] : 0); var hour = (values.Length > 3 ? (int)values[3] : 0); var min = (values.Length > 4 ? (int)values[4] : 0); var sec = (values.Length > 5 ? (int)values[5] : 0); var ms = (values.Length > 6 ? (int)values[6] : 0); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date // Note: Where Date is called as a constructor with more than one argument, the specifed arguments represent local time. var dt = new DateTime(year, month, day, hour, min, sec, ms, DateTimeKind.Local); if (type == typeof(DateTimeOffset)) return new DateTimeOffset(dt); return dt; } } } 

这里, ReadJson()将令牌加载到JConstructor ,检查构造函数名称是否为Date ,然后解析子JConstructor

注意我没有覆盖WriteJson ,所以这个转换器将以与JavaScriptDateTimeConverter相同的样式JavaScriptDateTimeConverter ,其中ticks显示为构造函数的单个参数。

用它代替JavaScriptDateTimeConverter()