You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何通过JsonConverter统一DateTime的JSON输出格式

解决Json.Net强制输出固定格式yyyy-MM-ddTHH:mm:ss.fffffff的DateTime问题

我明白你遇到的困扰——明明已经自定义了转换器生成带7位毫秒的日期字符串,可最终JSON输出还是自动省略了末尾的.0000000部分。让我来分析原因并给出正确的解决方案:

问题根源

  1. 第一种尝试(继承IsoDateTimeConverter):
    IsoDateTimeConverter内部会根据DateTime值的实际精度调整输出,当毫秒部分全为0时,它会自动省略毫秒段,即使你指定了完整的格式字符串。这是因为该转换器的设计初衷是兼容ISO 8601的不同精度变体,而非强制固定格式。

  2. 第二种尝试(自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:07:17