C# 如何使用JSON.Net转换新的日期(年、月、日)重载
我正在尝试解析JSON文件,其中日期定义为: 所以我试着用 test.json:C# 如何使用JSON.Net转换新的日期(年、月、日)重载,c#,datetime,json.net,C#,Datetime,Json.net,我正在尝试解析JSON文件,其中日期定义为: 所以我试着用 test.json: {"data" : [{"Date" : new Date(2015, 06, 01, 00, 00, 00)}]} c#: 不幸的是,我收到了这个错误: 意外的令牌分析日期。应为EndConstructor,但得到整数。路径“数据[0]。日期”,第13行,位置30 据我所知,JSON.Net最多只能使用新日期(52231943),但不能处理Javascript Date()对象的构造函数重载 是否有任何已知的方
{"data" : [{"Date" : new Date(2015, 06, 01, 00, 00, 00)}]}
c#:
不幸的是,我收到了这个错误:
意外的令牌分析日期。应为EndConstructor,但得到整数。路径“数据[0]。日期”,第13行,位置30
据我所知,JSON.Net最多只能使用新日期(52231943)
,但不能处理Javascript Date()对象的构造函数重载
是否有任何已知的方法来转换新日期(年、月、日)?您可以创建自己的子类,如下所示: 此处
ReadJson()
将令牌加载到中,检查日期是否为Date
,然后解析子项
注意:我没有重写WriteJson
,因此此转换器将以与JavaScriptDateTimeConverter
相同的样式编写,记号作为构造函数的单个参数出现
在您正在解析的文件中,使用它代替
JavaScriptDateTimeConverter()
,这些日期是否始终包含在如上所述的数组中?请注意,这实际上不是合法的“json”。它可能是一个有效的Javascript对象,但不是json。@LasseV.Karlsen-没错,不过json.NET支持这种语法。请参阅并按预期工作,除了JToken.Load()解析00到07之间的前导零,但在08和09时崩溃。我用:var json=Regex.Replace(输入,“()0*([1-9][0-9]*| 0)”,“$1$2”)@lucian.jp-很高兴它能为你工作。您介意分享一个导致崩溃的JSON示例吗?{“数据”:[{“日期”:new Date(2015,06,08,00,00)}]}@lucian.jp-我发现JsonTextReader
将以0
开头的数字解释为八进制,因此08
引发异常。(根据这些数字,不应该有前导零,因此这是标准的扩展。)看起来也没有解决方法:。因此,您的Regex.Replace()可能是正确的想法。@lucian.jp-八进制是基数8,因此八进制中没有8
数字。
{"data" : [{"Date" : new Date(2015, 06, 01, 00, 00, 00)}]}
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));
}
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;
}
}
}