如何让 JSON.NET 将 date/time 序列化为 ISO 8601?
How to get JSON.NET to serialize date/time to ISO 8601?
我有一个 Web API 应用程序,returns JSON 面向可能不使用 Microsoft 技术的消费者。当我的控制器 return 的对象的 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 配置中添加以下行似乎被忽略了,因为它在上面最初显示的日期继续到 return JSON :
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
我假设一旦我弄清楚了核心问题,Web API 问题也可能得到解决。
您获得的格式 是 ISO 8601 格式(请阅读维基百科中关于时间和时区指示符的部分),只是您的日期显然没有调整为 UTC 时间, 所以你得到的是附加到日期的时区偏移量,而不是 Z
祖鲁时区指示符。
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'"
};
添加到@Brian Rogers 的回答中,对于 ASP 核心,添加 Startup.cs
:
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options =>
options.SerializerSettings.Converters.Add(new IsoDateTimeConverter
{
DateTimeStyles = DateTimeStyles.AdjustToUniversal
}));
另一个选项:
string json = JsonConvert.SerializeObject(DateTime.Now, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});
我有一个 Web API 应用程序,returns JSON 面向可能不使用 Microsoft 技术的消费者。当我的控制器 return 的对象的 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 配置中添加以下行似乎被忽略了,因为它在上面最初显示的日期继续到 return JSON :
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
我假设一旦我弄清楚了核心问题,Web API 问题也可能得到解决。
您获得的格式 是 ISO 8601 格式(请阅读维基百科中关于时间和时区指示符的部分),只是您的日期显然没有调整为 UTC 时间, 所以你得到的是附加到日期的时区偏移量,而不是 Z
祖鲁时区指示符。
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'"
};
添加到@Brian Rogers 的回答中,对于 ASP 核心,添加 Startup.cs
:
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options =>
options.SerializerSettings.Converters.Add(new IsoDateTimeConverter
{
DateTimeStyles = DateTimeStyles.AdjustToUniversal
}));
另一个选项:
string json = JsonConvert.SerializeObject(DateTime.Now, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});