如何让 JSON.NET 将日期/时间序列化为 ISO 8601? [英] How to get JSON.NET to serialize date/time to ISO 8601?

查看:20
本文介绍了如何让 JSON.NET 将日期/时间序列化为 ISO 8601?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Web API application that returns JSON to consumers who may not be using Microsoft technologies. When my controller returns an object with DateTime properties as JSON, it serializes the date in this format:

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

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

This is giving the consumer a bit of a headache as they're expect it to be in ISO 8601 format. Some research has told me that JSON.NET now uses ISO 8601 by default (I am using 9.0.1). When I run this code...

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

...我明白了:

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

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

Wikipedia shows these as valid ISO 8601 formats when expressing full date and time:

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

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

However, the output I got above doesn't exactly match any of those. I want the formatter to use 2017-03-15T11:45:42Z.

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

And probably worthy of another question altogether, adding the below line in my Web API config seems to be ignored as it continues to return JSON in the date originally shown above:

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

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

I assume that once I figure out the core issue, the Web API issue may also be resolved.

推荐答案

你得到的格式 ISO 8601 格式(阅读 Wikipedia 中有关时间和时区指示符的部分),就是这样您的日期显然没有调整为 UTC 时间,因此您将获得附加到日期而不是 Z Zulu 时区指示器的时区偏移量.

The format you are getting is ISO 8601 format (read the section on Times and Time Zone Designators in Wikipedia), it's just that your dates are apparently not adjusted to UTC time, so you are getting a timezone offset appended to the date rather than the Z Zulu timezone indicator.

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

The IsoDateTimeConverter has settings you can use to customize its output. You can make it automatically adjust dates to UTC by setting DateTimeStyles to AdjustToUniversal. You can also customize the output format to omit the fractional seconds if you don't want them. By default, the converter does not adjust to UTC time and includes as many decimals of precision as there are available for the seconds.

试试这个:

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 指令.

If your dates are already UTC, but the DateTimeKind on them is not set to Utc like it should be (e.g. it is Unspecified), then ideally you should fix your code so that this indicator is set correctly prior to serializing. However, if you can't (or don't want to) do that, you can work around it by changing the converter settings to always include the Z indicator in the date format (instead of using the K specifier which looks at the DateTimeKind on the date) and removing the AdjustToUniversal directive.

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

这篇关于如何让 JSON.NET 将日期/时间序列化为 ISO 8601?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆