求助:如何通过JsonConverter统一DateTime的JSON输出格式
解决Json.Net强制输出固定格式
yyyy-MM-ddTHH:mm:ss.fffffff的DateTime问题 我明白你遇到的困扰——明明已经自定义了转换器生成带7位毫秒的日期字符串,可最终JSON输出还是自动省略了末尾的.0000000部分。让我来分析原因并给出正确的解决方案:
问题根源
第一种尝试(继承
IsoDateTimeConverter):IsoDateTimeConverter内部会根据DateTime值的实际精度调整输出,当毫秒部分全为0时,它会自动省略毫秒段,即使你指定了完整的格式字符串。这是因为该转换器的设计初衷是兼容ISO 8601的不同精度变体,而非强制固定格式。第二种尝试(自定义
DateTimeConverterBase):
你用WriteRawValue直接写入字符串的方式有问题——WriteRawValue用于写入原始JSON片段,但你传入的dt_str是不带引号的日期字符串,JsonWriter自动添加引号的同时,触发了内部的日期格式优化逻辑,导致毫秒段被截断。
正确的自定义转换器实现
要强制输出固定格式的日期字符串,我们需要绕过JsonWriter的自动优化,直接写入预格式化好的带引号字符串,同时确保反序列化能正确解析格式:
public class FixedFormatDateTimeConverter : Newtonsoft.Json.Converters.DateTimeConverterBase { private const string DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffffff"; public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value is DateTime dateTime) { // 直接写入带引号的格式化日期字符串,避免JsonWriter干预 string formattedDate = $"\"{dateTime.ToString(DateTimeFormat, CultureInfo.InvariantCulture)}\""; writer.WriteRawValue(formattedDate); } else { throw new ArgumentException("Value must be a DateTime", nameof(value)); } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.String) { // 严格按指定格式解析日期 if (DateTime.TryParseExact(reader.Value.ToString(), DateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result)) { return result; } } throw new JsonSerializationException($"Unable to parse value as DateTime with format {DateTimeFormat}"); } }
应用转换器的正确方式
- 属性级标记:直接在DateTime属性上添加特性:
[JsonConverter(typeof(FixedFormatDateTimeConverter))] public DateTime created_utc; - 全局配置:如果需要对所有DateTime生效,配置到
JsonSerializerSettings:var settings = new JsonSerializerSettings { Converters = new List<JsonConverter> { new FixedFormatDateTimeConverter() }, // 注意:不要设置DateFormatString,否则会覆盖转换器的行为 }; string json = JsonConvert.SerializeObject(yourObject, settings);
验证效果
现在序列化DateTime.MinValue时,会输出符合要求的27字符格式:
"0001-01-01T00:00:00.0000000"
内容的提问来源于stack exchange,提问作者bdcoder
相关产品推荐
相关产品推荐

