如何在System.Text.Json反序列化时去除DateTime的毫秒值?
最优解决方案:自定义JSON转换器
针对你需要批量处理DateTime去毫秒的场景,**自定义JsonConverter<DateTime>**是最优雅的方案,无需在每个类里重复写处理方法,一次配置即可全局生效或按需指定。
步骤1:实现自定义DateTime转换器
创建一个转换器,在反序列化阶段直接截断毫秒部分:
using System.Text.Json; using System.Text.Json.Serialization; public class DateTimeWithoutMillisecondsConverter : JsonConverter<DateTime> { public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var dateTime = reader.GetDateTime(); // 通过截断Ticks去掉毫秒部分,比ToString再转换性能更好 return dateTime.AddTicks(-(dateTime.Ticks % TimeSpan.TicksPerSecond)); } public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { // 序列化时也输出不带毫秒的格式(可选,根据业务需求调整) writer.WriteStringValue(value.ToString("yyyy-MM-ddTHH:mm:ss")); } }
步骤2:全局注册转换器(推荐)
如果所有DateTime类型都需要去掉毫秒,在JsonSerializerOptions里全局注册,一次配置后所有反序列化操作都会自动处理:
var options = new JsonSerializerOptions { Converters = { new DateTimeWithoutMillisecondsConverter() }, // 其他序列化配置(如忽略空值等)... }; // 反序列化示例 var opened = JsonSerializer.Deserialize<Opened>(jsonString, options); // 此时opened.eventTime已自动去除毫秒
步骤3:按需指定转换器(针对特定属性)
如果只有部分DateTime属性需要处理,直接在对应属性上标记特性即可:
public class Opened { public int campaignId { get; set; } public int count { get; set; } [JsonConverter(typeof(DateTimeWithoutMillisecondsConverter))] public DateTime eventTime { get; set; } }
替代方案:扩展方法简化现有逻辑
如果暂时不想修改序列化配置,也可以给DateTime写一个全局扩展方法,替代每个类里重复的eventTimeNoMS()方法:
public static class DateTimeExtensions { public static DateTime TruncateToSecond(this DateTime dateTime) { return dateTime.AddTicks(-(dateTime.Ticks % TimeSpan.TicksPerSecond)); } } // 使用时直接调用: var noMsTime = opened.eventTime.TruncateToSecond();
这种方式比重复写方法更简洁,但需要手动调用,不如转换器自动处理省心。
内容的提问来源于stack exchange,提问作者Dayton Brown
相关产品推荐
相关产品推荐

