强制JSON.NET在序列化DateTime时包含毫秒(即使ms组件为零)
本文关键字:ms 即使 组件 包含毫 NET JSON 序列化 DateTime 强制 | 更新日期: 2023-09-27 18:27:26
我使用JSON.NET直接从对象实例序列化DateTime值(不使用带格式化程序的DateTime.ToString())。
有没有办法强制JSON.NET在序列化中包含毫秒,即使DateTime的毫秒组件为零?
背景:对于这个JSON端点,我有一个非常慢的web服务使用者。条件逻辑对消费者来说是昂贵的,所以我希望每次都提供相同的数据格式。
我们在当前项目中遇到了同样的问题。我们使用Web API(以及JSON.Net)来实现REST API。我们发现,在序列化DateTime
对象时,JSON.Net会从毫秒中省略尾随的零,或者如果为零,则会从日期中完全省略毫秒。我们的客户期望有一个固定长度的日期-时间字符串,正好有3位数字表示毫秒。我们通过在Application_Start()
中执行以下操作修复了它:
JsonSerializerSettings settings = HttpConfiguration.Formatters.JsonFormatter.SerializerSettings;
IsoDateTimeConverter dateConverter = new IsoDateTimeConverter
{
DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff'Z'"
};
settings.Converters.Add(dateConverter);
如果您不使用Web API,您也可以通过创建JsonSerializerSettings
的新实例,如上所示向其添加IsoDateTimeConverter
,然后将序列化程序设置传递给JsonConvert.SerializeObject()
来完成同样的操作。
注意:如果要序列化DateTimeOffset
或本地DateTime
,并且希望包含时区偏移量,请将上述格式中引用的'Z'
替换为未引用的K
。有关详细信息,请参阅文档中的自定义日期和时间格式字符串。
对于任何找到这个答案并想要解析这种.NET默认格式的时间戳的Java用户,我想注意一种Java 8(java.time.*
)解析格式的方法:
public static final DateTimeFormatter FORMATTER =
new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd'T'HH:mm:ss")
.appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true)
.toFormatter();
...
LocalDateTime ldt = LocalDateTime.parse(dateString, FORMATTER);
这表示期望0-3位小数毫秒,true
表示期望的小数点。它正确地将".47"解释为470毫秒。
我在使用JsonWriter时遇到了这个问题,需要解决它,因为我们观察到像Day.js这样的Javascript日期库更喜欢毫秒而不是3位数。这个问题让我找到了解决方案,所以我想分享一下,以防其他人有像我这样的用例:
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter writer = new JsonTextWriter(sw)) {
writer.Formatting = Newtonsoft.Json.Formatting.None;
writer.DateFormatString="yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff''";
writer.WriteStartObject();
DateTime? date = new DateTime(2021,12,30,23,59,40,250);
writer.WritePropertyName("Date1");
writer.WriteValue(date);
date = new DateTime(2021, 12, 30, 23, 59, 40, 555);
writer.WritePropertyName("Date2");
writer.WriteValue(date);
date = new DateTime(2021, 12, 30, 23, 59, 40, 0);
writer.WritePropertyName("Date3");
writer.WriteValue(date);
date = null;
writer.WritePropertyName("DateNULL");
writer.WriteValue(date);
writer.WriteEndObject();
}
Console.WriteLine(sb.ToString());
这产生:
{
"Date1": "2021-12-30T23:59:40.250",
"Date2": "2021-12-30T23:59:40.555",
"Date3": "2021-12-30T23:59:40.000",
"DateNULL": null
}
我需要添加的重要行是:
writer.DateFormatString="yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff''";