【问题标题】:How to get JSON.NET to serialize date/time to ISO 8601?如何让 JSON.NET 将日期/时间序列化为 ISO 8601?
【发布时间】:2017-08-06 06:56:39
【问题描述】:

我有一个 Web API 应用程序,可将 JSON 返回给可能未使用 Microsoft 技术的消费者。当我的控制器以 JSON 形式返回具有 DateTime 属性的对象时,它会以这种格式序列化日期:

2017-03-15T00:00:00-04:00

这让消费者有点头疼,因为他们希望它采用 ISO 8601 格式。一些研究告诉我 JSON.NET 现在默认使用 ISO 8601(我使用的是 9.0.1)。当我运行这段代码时......

Clipboard.Copy(JsonConvert.SerializeObject(DateTime.Now));

...我明白了:

2017-03-15T09:10:13.8105498-04:00

在表达完整日期和时间时,维基百科将这些显示为有效的 ISO 8601 格式:

2017-03-15T11:45:42+00:00
2017-03-15T11:45:42Z
20170315T114542Z

但是,我上面得到的输出与其中任何一个都不完全匹配。我希望格式化程序使用2017-03-15T11:45:42Z

并且可能完全值得另一个问题,在我的 Web API 配置中添加以下行似乎被忽略了,因为它继续在上面最初显示的日期返回 JSON:

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter());

我假设一旦我弄清楚了核心问题,Web API 问题也可能会得到解决。

【问题讨论】:

  • 我希望我能多次投票。更多人应该关注采用 ISO 8601 格式的 JSON 日期。

标签: json asp.net-web-api json.net iso8601


【解决方案1】:

你得到的格式 ISO 8601 格式(阅读维基百科中关于时间和时区指示符的部分),只是你的日期显然没有调整到 UTC 时间,所以你得到附加到日期而不是 Z Zulu 时区指示器的时区偏移量。

IsoDateTimeConverter 具有可用于自定义其输出的设置。您可以通过将DateTimeStyles 设置为AdjustToUniversal 使其自动将日期调整为UTC。如果您不想要它们,您还可以自定义输出格式以省略小数秒。默认情况下,转换器不会根据 UTC 时间进行调整,并且会包含可用于秒的尽可能多的精度小数。

试试这个:

IsoDateTimeConverter converter = new IsoDateTimeConverter
{
    DateTimeStyles = DateTimeStyles.AdjustToUniversal,
    DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK"
};

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(converter);

如果您的日期已经是 UTC,但它们上的 DateTimeKind 没有像应有的那样设置为 Utc(例如它是 Unspecified),那么理想情况下,您应该修复您的代码,以便设置此指标在序列化之前正确。但是,如果您不能(或不想)这样做,您可以通过更改转换器设置以始终在日期格式中包含 Z 指示符来解决它(而不是使用 K 说明符查看日期的DateTimeKind)并删除AdjustToUniversal指令。

IsoDateTimeConverter converter = new IsoDateTimeConverter
{
    DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
};

【讨论】:

  • 很好的答案,谢谢。我使用了您最初示例的一部分,最后只使用了DateTimeStyles = DateTimeStyles.AdjustToUniversal 没有格式,它输出为2017-03-15T04:00:00Z,就像我想要的那样。
  • 很好的答案。请注意将此添加到WebApiConfig.cs 文件中。我还使用了Culture = System.Globalization.CultureInfo.InvariantCultureDateTimeFormat = "o",它们产生了这样的序列化日期2014-12-10T17:32:44.4930000Z
【解决方案2】:

添加到@Brian Rogers 的答案,对于 ASP Core,添加 Startup.cs

services.AddMvc()
  .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
  .AddJsonOptions(options =>
    options.SerializerSettings.Converters.Add(new IsoDateTimeConverter
    {
      DateTimeStyles = DateTimeStyles.AdjustToUniversal
    }));

【讨论】:

  • 对不起,不起作用..另外,如果你想特定于核心,也许使用 .AddMvcCore() ?
【解决方案3】:

另一种选择:

string json = JsonConvert.SerializeObject(DateTime.Now, new JsonSerializerSettings
{
     DateTimeZoneHandling = DateTimeZoneHandling.Utc
});

【讨论】:

    猜你喜欢
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    相关资源
    最近更新 更多