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

C#中序列化含DateOnly与TimeOnly的对象至JSON文件失败问题

解决Newtonsoft.Json序列化DateOnly/TimeOnly类型的问题

Newtonsoft.Json默认不支持.NET 6+引入的DateOnly和TimeOnly类型,需要自定义JSON转换器来处理这两个类型的序列化与反序列化逻辑。以下是具体解决方案:

1. 自定义JSON转换器

创建两个转换器类,分别处理DateOnly和TimeOnly的格式转换:

// DateOnly转换器
public class DateOnlyConverter : JsonConverter<DateOnly>
{
    private const string DefaultDateFormat = "yyyy-MM-dd";

    public override DateOnly ReadJson(JsonReader reader, Type objectType, DateOnly existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        return DateOnly.ParseExact(reader.Value.ToString(), DefaultDateFormat, CultureInfo.InvariantCulture);
    }

    public override void WriteJson(JsonWriter writer, DateOnly value, JsonSerializer serializer)
    {
        writer.WriteValue(value.ToString(DefaultDateFormat, CultureInfo.InvariantCulture));
    }
}

// TimeOnly转换器
public class TimeOnlyConverter : JsonConverter<TimeOnly>
{
    private const string DefaultTimeFormat = "HH:mm:ss";

    public override TimeOnly ReadJson(JsonReader reader, Type objectType, TimeOnly existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        return TimeOnly.ParseExact(reader.Value.ToString(), DefaultTimeFormat, CultureInfo.InvariantCulture);
    }

    public override void WriteJson(JsonWriter writer, TimeOnly value, JsonSerializer serializer)
    {
        writer.WriteValue(value.ToString(DefaultTimeFormat, CultureInfo.InvariantCulture));
    }
}

2. 应用转换器

有两种方式可以让Newtonsoft.Json使用这些转换器:

方式一:在类属性上标记特性

直接在information类的对应字段上添加[JsonConverter]特性:

public class information
{
    [JsonProperty]
    [JsonConverter(typeof(DateOnlyConverter))]
    public DateOnly date;
    
    [JsonProperty]
    public string summary;
    
    [JsonProperty]
    [JsonConverter(typeof(TimeOnlyConverter))]
    public TimeOnly endTime;
    
    [JsonProperty]
    [JsonConverter(typeof(TimeOnlyConverter))]
    public TimeOnly startTime;
}

方式二:全局配置转换器

如果项目中有多处使用DateOnly/TimeOnly序列化,建议全局配置转换器,避免重复标记:

var jsonSettings = new JsonSerializerSettings();
jsonSettings.Converters.Add(new DateOnlyConverter());
jsonSettings.Converters.Add(new TimeOnlyConverter());

3. 修正序列化代码

同时优化文件写入逻辑,避免流操作的潜在问题(如文件不存在时的异常、覆盖不完整等):

private static void WriteFile(DateOnly date, string summary, TimeOnly startTime, TimeOnly endTime)
{
    var newAppointment = new information()
    {
        date = date,
        summary = summary,
        startTime = startTime,
        endTime = endTime
    };

    var appointmentList = GetJsonInfo();
    appointmentList.Add(newAppointment);

    // 使用全局配置序列化
    var jsonSettings = new JsonSerializerSettings();
    jsonSettings.Converters.Add(new DateOnlyConverter());
    jsonSettings.Converters.Add(new TimeOnlyConverter());
    string jsonContent = JsonConvert.SerializeObject(appointmentList, Formatting.Indented, jsonSettings);

    // 用File.WriteAllText简化文件操作
    string fullPath = Path.Combine(_appointmentPath, "appointment.json");
    File.WriteAllText(fullPath, jsonContent, Encoding.UTF8);
}

// 补充GetJsonInfo方法的反序列化逻辑(需同步使用转换器)
private static List<information> GetJsonInfo()
{
    string fullPath = Path.Combine(_appointmentPath, "appointment.json");
    if (!File.Exists(fullPath))
    {
        return new List<information>();
    }

    string jsonContent = File.ReadAllText(fullPath);
    var jsonSettings = new JsonSerializerSettings();
    jsonSettings.Converters.Add(new DateOnlyConverter());
    jsonSettings.Converters.Add(new TimeOnlyConverter());
    
    return JsonConvert.DeserializeObject<List<information>>(jsonContent, jsonSettings) ?? new List<information>();
}

关键说明

  • 序列化和反序列化必须使用相同的转换器配置,否则会出现格式不匹配的错误
  • 可以根据需求修改转换器中的日期/时间格式字符串(如yyyy/MM/dd或HH:mm)

内容的提问来源于stack exchange,提问作者SoldatXwing

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:20:50