强制JSON.NET在序列化DateTime时包含毫秒(即使ms组件为零)

时间:2013-08-12 17:42:05

标签: c# json datetime serialization json.net

我使用JSON.NET直接从对象实例序列化DateTime值(不使用带格式化程序的DateTime.ToString())。

有没有办法强制JSON.NET在序列化中包含毫秒,即使DateTime的毫秒组件为零?

背景:我对此JSON端点的Web服务使用者非常慢。条件逻辑对于消费者来说是昂贵的,因此我希望每次都提供相同的数据格式。

3 个答案:

答案 0 :(得分:40)

我们在当前项目中遇到了同样的问题。我们使用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,然后将序列化设置传递给{{}}来执行相同的操作。 {1}}。

注意:如果您要序列化JsonConvert.SerializeObject()或本地DateTimeOffset,并且希望包含时区偏移量,请将上述格式中引用的DateTime替换为不带引号的'Z' 1}}。 有关详细信息,请参阅文档中的Custom Date and Time Format Strings

答案 1 :(得分:1)

对于所有找到此答案并希望解析.NET默认格式的时间戳的Java人,我想指出一种Java 8(java.time.*)方法来解析该格式:

public static final DateTimeFormatter FORMATTER =
    new DateTimeFormatterBuilder().appendPattern("yyyy-M-d'T'H:m:s")
                                  .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true)
                                  .toFormatter();
...
LocalDateTime ldt = LocalDateTime.parse(dateString, FORMATTER);

这表示期望0到3的小数位数字,其中true是期​​望的小数点。它可以正确地将“ .47”解释为470毫秒。

答案 2 :(得分:0)

我在使用 JsonWriter 时遇到了这个问题并需要解决它,因为我们观察到 Javascript 日期库(例如 Day.js)更喜欢毫秒而不是 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''";