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

设置JsonSerializerSettings为en-US,回历日期反序列化仍用ar文化,原因何在?

问题分析与解决方案

你遇到的这个问题,核心原因其实和Json.NET的Culture设置作用范围有关——它并不影响ISO 8601格式日期的解析,而你JSON里的"2018-01-02T00:00:00"正好是标准的ISO日期格式。

为什么会出现回历日期?

Json.NET对ISO格式的日期字符串有专门的解析逻辑,会直接按公历(Gregorian Calendar)解析成DateTime对象,和你设置的Culture无关。你看到的15/04/39其实不是反序列化的问题,而是后续显示该DateTime时,使用了阿拉伯文化(ar)的回历(Hijri)格式。DateTime本身存储的是公历的时间戳(Ticks),只是输出时被当前线程的文化设置转换成了回历的展示形式。

验证方法

你可以在反序列化后打印以下内容确认:

// 打印Ticks,这个值是公历时间的唯一标识,和文化无关
Console.WriteLine(model.EffectiveStartDate.Value.Ticks);
// 强制用公历文化输出,看是否符合预期
Console.WriteLine(model.EffectiveStartDate.Value.ToString("dd/MM/yyyy", new System.Globalization.CultureInfo("en-US")));

如果输出的Ticks对应公历2018-01-02,且第二个打印语句显示02/01/2018,就说明反序列化是正确的,只是显示环节的问题。

解决方案

根据你的需求,有两种处理方式:

  • 方式一:显示时指定公历文化
    当你需要输出日期时,明确指定使用en-US文化(公历)来格式化:
    var formattedDate = effectiveStartDate?.ToString("dd/MM/yyyy", new CultureInfo("en-US"));
    
  • 方式二:确保线程默认文化为公历
    如果你的整个应用都需要用公历展示日期,可以在程序启动时设置线程的默认文化:
    System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
    System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
    
    (注意:ASP.NET等Web应用需要在请求级别设置,避免多线程冲突)

补充说明

如果你的JSON日期是非ISO格式(比如"01/02/2018"),那JsonSerializerSettings.Culture才会生效——它会告诉Json.NET按照指定文化的规则去解析这种模糊的日期字符串。但对于ISO格式,这个设置是无效的,因为ISO格式本身就是无歧义的公历标准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:53:38