Json.Net 不一致地反序列化日期时间



我在使用 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 始终以相同的格式返回日期时间?

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

jo["time"]

(最终(将实际DateTime值写入控制台。正如@JonSkeet指出的那样,您实际上是在向控制台写入JValue - JValue.ToString只是调用包装值的ToString方法,在您的情况下是DateTime.ToString()

换句话说:

  • 调用 Console.WriteLine 并传递 JValue 实例会使用占用objectConsole.WriteLine 重载。
  • 这种重载调用.ToString() JValue
  • 然后调用基础类型的.ToString()(在您的情况下为 DateTime
  • (

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

更有趣的一点是jo.Value<string>("time")线。在后台,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 */);

相关内容

  • 没有找到相关文章

最新更新