如何用System.Text.Json解析含24:00的ISO8601-2004时间至System.DateTime
处理System.Text.Json反序列化中的ISO8601-2004 24:00时间格式问题
针对API返回的2022-11-21T24:00:00.000Z这类已被现行ISO8601标准移除的24小时制时间格式,你可以通过自定义System.Text.Json转换器来处理,自动将其修正为合法的DateTime值,同时调整日期到次日的00:00。
实现自定义DateTime转换器
创建一个继承自JsonConverter<DateTime>的类,在读取JSON时处理特殊的24:00格式:
using System; using System.Text.Json; using System.Text.Json.Serialization; public class Iso8601LegacyTimeConverter : JsonConverter<DateTime> { public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var dateString = reader.GetString(); if (string.IsNullOrEmpty(dateString)) { return default; } // 检查是否包含24:00格式 if (dateString.Contains("T24:")) { // 将24:替换为00:,解析后加1天得到正确时间 var correctedString = dateString.Replace("T24:", "T00:"); var baseDate = DateTime.ParseExact(correctedString, "yyyy-MM-ddTHH:mm:ss.fffZ", null, System.Globalization.DateTimeStyles.RoundtripKind); return baseDate.AddDays(1); } // 正常格式直接解析 return DateTime.ParseExact(dateString, "yyyy-MM-ddTHH:mm:ss.fffZ", null, System.Globalization.DateTimeStyles.RoundtripKind); } public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { // 序列化时输出标准ISO8601格式 writer.WriteStringValue(value.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")); } }
使用转换器的两种方式
方式1:全局配置转换器
在JsonSerializerOptions中添加自定义转换器,全局生效:
var options = new JsonSerializerOptions(); options.Converters.Add(new Iso8601LegacyTimeConverter()); // 反序列化示例 var json = "{\"EventTime\":\"2022-11-21T24:00:00.000Z\"}"; var result = JsonSerializer.Deserialize<YourModel>(json, options); // result.EventTime 将是 2022-11-22T00:00:00.000Z
方式2:为单个属性标记转换器
直接在模型的DateTime属性上添加[JsonConverter]特性,仅对该属性生效:
public class YourModel { [JsonConverter(typeof(Iso8601LegacyTimeConverter))] public DateTime EventTime { get; set; } } // 反序列化时无需额外配置 var json = "{\"EventTime\":\"2022-11-21T24:00:00.000Z\"}"; var result = JsonSerializer.Deserialize<YourModel>(json);
关键逻辑说明
- 识别包含
T24:的时间字符串,将其替换为T00:,此时解析得到的是原日期的00:00 - 对解析后的日期加1天,得到正确的次日00:00时间,符合
24:00代表当日结束、次日开始的语义 - 序列化时输出标准ISO8601格式,避免产生不兼容的时间字符串
内容的提问来源于stack exchange,提问作者I am not Fat
相关产品推荐
相关产品推荐

