我正在使用 JSON.NET 直接从对象实例序列化 DateTime 值(不使用 DateTime.ToString() 和格式化程序)。
即使 DateTime 的毫秒部分为零,是否有办法强制 JSON.NET 在序列化中包含毫秒?
背景:对于这个 JSON 端点,我有一个非常慢的 Web 服务使用者。条件逻辑对消费者来说很昂贵,所以我想每次都提供相同的数据格式。
我正在使用 JSON.NET 直接从对象实例序列化 DateTime 值(不使用 DateTime.ToString() 和格式化程序)。
即使 DateTime 的毫秒部分为零,是否有办法强制 JSON.NET 在序列化中包含毫秒?
背景:对于这个 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()
注意:如果您要序列化 aDateTimeOffset
或 localDateTime
并且想要包含时区偏移量,请将'Z'
上述格式中的引用替换为未引用的K
. 有关详细信息,请参阅文档中的自定义日期和时间格式字符串。
我在使用 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''";
对于任何找到此答案并希望解析此类 .NET 默认格式时间戳的 Java 人员,我想指出一种java.time.*
用于解析格式的 Java 8 ( ) 方法:
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 毫秒。