【问题标题】:Json.Net deserialising DateTimes inconsistentlyJson.Net 不一致地反序列化 DateTime
【发布时间】:2014-12-17 15:58:34
【问题描述】:

我在使用 Json.Net 6.0.3 反序列化日期时间时遇到问题(我可以在 6.0.6 上复制该问题)。代码在 Windows 8.1 上的 .Net 4.5 中运行,文化为 en-GB。

这说明了问题:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

var d1 = new DateTimeOffset(2014, 12, 15, 18, 0, 0, TimeSpan.FromHours(1));
var obj = new {
    time = d1
};

var json = JsonConvert.SerializeObject(obj, Formatting.Indented);
Console.WriteLine(json);

var jo = JObject.Parse(json);

Console.WriteLine(jo.Value<string>("time") + " // jo.Value<string>(\"time\")");
Console.WriteLine(jo["time"] + " // jo[\"time\"]");

输出:

{
    "time": "2014-12-15T18:00:00+01:00"
}
12/15/2014 17:00:00 // jo.Value<string>("time")
15/12/2014 17:00:00 // jo["time"]

日期时间因访问 JObject 的方式而异 - 一种是 MM/DD/YYYY DD/MM/YYYY。这是为什么呢?

我不需要它们采用特定格式:问题在于格式会发生变化。我有很多遗留代码可以解析来自 Json.Net 的日期时间字符串。该代码还将在世界各地的不同计算机上运行,​​可能具有不同的文化。

有没有办法让 Json.Net 总是以相同的格式返回日期时间?

【问题讨论】:

    标签: c# json date datetime json.net


    【解决方案1】:

    问题在于这两行做不同的事情:

    jo["time"]
    

    正在(最终)将实际的DateTime 值写入控制台。作为@JonSkeet points out,您实际上是在将JValue 写入控制台--JValue.ToString just calls the wrapped value's ToString method though,在您的情况下为DateTime.ToString()

    换句话说:

    • 调用Console.WriteLine 并传递JValue 的实例会使用Console.WriteLine 的重载,它接受object
    • 重载在JValue 上调用.ToString()
    • 然后在基础类型上调用.ToString()(在您的情况下为DateTime

    因此,您将获得当前文化的默认格式。更具体地说,您将在当前文化中使用“G”说明符格式化DateTime

    更有趣的是jo.Value&lt;string&gt;("time") 行。 Under the hood,JSON.NET 正在使用以下方法将底层 DateTime 转换为字符串:

    Convert.ChangeType(value, typeof(string), CultureInfo.InvariantCulture);
    

    当然,这会产生一个完全不同的字符串,因为它明确使用CultureInfo.InvariantCulture

    从中得出的结论是,您最好的选择可能是将日期检索为DateTime,然后按照您想要的确切方式对其进行格式化,以避免任何歧义:

    DateTime dt = jo.Value<DateTime>("time");
    string dateTimeSTring = dt.ToString(/* whatever format you always want */);
    

    【讨论】:

    • @JonSkeet:嗯,是的,我把它简化了,但是JValueToString 方法调用了基础值的(在这种情况下是DateTimeToString 方法。
    • 对。如果我是你,我不会过度简化它。基本前提是好的(这就是我放弃自己的答案的原因),但是当整个地方都涉及转换时,最好准确地说出这一点。
    猜你喜欢
    • 1970-01-01
    • 2012-08-05
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    相关资源
    最近更新 更多