如何让JSON.NET将日期/时间序列化为ISO 8601?

时间:2017-03-15 13:36:41

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

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

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问题。

3 个答案:

答案 0 :(得分:20)

您获得的格式 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指示符(而不是使用{{1在日期查看K并删除DateTimeKind指令的说明符。

AdjustToUniversal

答案 1 :(得分:2)

另一个选择:

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

答案 2 :(得分:0)

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

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