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

.NET Core从3.1升级到5.0后时区处理逻辑变更引发日期参数解析异常

问题产生原因
  • .NET Core 3.1版本中,Web API默认使用的System.Text.Json序列化器,会将携带Z标识的UTC时间格式参数自动转换为服务器本地时区对应的DateTime值,解析后对象的Kind属性为DateTimeKind.Local,你观测到的+3小时差值就是部署API的服务器本地时区与UTC时区的偏移量。
  • 升级到.NET 5.0后,官方调整了System.Text.Json的默认日期解析规则,携带Z标识的UTC时间会被直接解析为UTC时间,不会自动做本地时区转换,解析后对象的Kind属性为DateTimeKind.Utc,因此出现了解析值的差异。
可行解决方案

你可以根据业务实际情况选择以下任意一种方案修复:

方案1:全局配置序列化规则,恢复3.1版本的行为

该方案不需要修改业务代码,仅需修改启动配置即可兼容原有逻辑。

若使用默认System.Text.Json序列化器

先自定义日期转换类:

public class LocalTimeDateTimeConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TryGetDateTime(out DateTime dateTime))
        {
            return dateTime.Kind switch
            {
                DateTimeKind.Utc => dateTime.ToLocalTime(),
                DateTimeKind.Unspecified => DateTime.SpecifyKind(dateTime, DateTimeKind.Local),
                _ => dateTime
            };
        }
        return default;
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        // 序列化输出规则可根据业务需求调整,示例是统一输出UTC格式时间
        writer.WriteStringValue(value.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
    }
}

再在启动配置中注册该转换器:

// .NET 6+ 顶层语句写法
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new LocalTimeDateTimeConverter());
    });

// .NET 5 带Startup类写法
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.Converters.Add(new LocalTimeDateTimeConverter());
        });
}

若使用Newtonsoft.Json序列化器

直接配置序列化设置即可:

builder.Services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
    });

方案2:调整业务代码适配UTC时间

该方案长期更规范,可避免多节点部署时区不一致导致的时间问题。将原有依赖本地时间的业务逻辑全部调整为使用UTC时间计算、存储,返回给前端时再按需转换为对应用户的时区时间即可。

方案3:使用DateTimeOffset类型接收日期参数

DateTimeOffset自带时区偏移信息,不存在自动转换的歧义,解析和计算的稳定性更高。只需将参数类中的DateTime类型替换为DateTimeOffset即可:

public class DateQueryParam
{
    public DateTimeOffset CreatedOnGreaterThan { get; set; }
    public DateTimeOffset CreatedOnLessThan { get; set; }
}

后续需要本地时间时调用LocalDateTime属性,需要UTC时间时调用UtcDateTime属性即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:24:02