json日期问题本质是时区语义一致性,而非显示格式;newtonsoft.json中unspecified被误当本地时间导致跨时区解析偏差,应统一存utc并配roundtripkind,system.text.json需自定义转换器控制序列化与反序列化行为。

JSON 日期格式问题本质不是“怎么改显示”,而是“时区语义是否一致”。用 DateFormatString 硬塞格式,不处理 DateTimeKind,90% 的线上时间错乱都源于此。
Newtonsoft.Json 中 DateTimeKind.Unspecified 被当成本地时间?
这是最隐蔽的坑:当 DateTimeKind.Unspecified 值被序列化,默认行为会按当前服务器本地时区解释(比如 +08:00),但前端 new Date("2026-04-23T10:00:00") 在 Chrome 和 Safari 中解析结果可能差 8 小时。
- 别用
DateTimeZoneHandling.AssumeLocal—— 它会把所有Unspecified强行转成本地时间,跨时区部署直接翻车 - 推荐统一存
Utc:入库/赋值前调用.ToUniversalTime(),再配DateTimeZoneHandling.RoundtripKind - 若必须保留本地标识,
DateFormatHandling.IsoDateFormat(默认)+DateTimeZoneHandling.RoundtripKind才能确保反序列化后Kind == DateTimeKind.Local -
DateFormatString = "yyyy-MM-dd HH:mm:ss"只控制字符串样子,不解决时区歧义;它输出的字符串不含时区偏移,JS 解析时默认当作本地时间
System.Text.Json 怎么统一改 DateTime 输出格式?
它没有全局 DefaultSettings,AddJsonOptions 配置对 ReadFromJsonAsync<t>()</t> 无效 —— 因为后者用的是独立的、未共享的 JsonSerializerOptions 实例。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 必须显式传入选项:比如
await req.ReadFromJsonAsync<mydto>(sharedOptions)</mydto> - 自定义转换器是唯一可靠方式:
options.Converters.Add(new JsonConverter<datetime>())</datetime>,并在Write方法里用value.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) - 反序列化时注意:
System.Text.Json默认把任何输入都设为Unspecified,如需还原原始Kind,得在转换器中手动读取"Z"或+08:00后缀并设置DateTimeKind - 别指望
JsonStringEnumConverter对 DateTime 生效 —— 它只管 enum
ASP.NET Core 全局配置后,HttpContext.Request 还是默认格式?
因为 AddJsonOptions 只影响 MVC 的 Model Binding 和 JsonResult,不影响底层 HttpRequest 的 ReadFromJsonAsync —— 后者走的是 System.Text.Json 默认路径,不读取 MVC 的配置。
- 解决方案只有两个:封装一个带共享
JsonSerializerOptions的扩展方法,或在每个ReadFromJsonAsync调用处显式传参 - 若用
Newtonsoft.Json替换默认序列化器(通过AddNewtonsoftJson),则ReadFromJsonAsync仍不会自动用它 —— 这个 API 是硬绑定System.Text.Json的 - DTO 层建议只留一个
DateTime字段,配合转换器做单点控制;避免在多个属性上分散写[JsonConverter],维护成本高且易漏
真正难的不是写出格式字符串,而是让前后端对“这个时间到底属于哪个时区”达成共识。一旦业务涉及多时区用户、定时任务或数据库时间比对,DateTimeKind 的处理就不再是可选项,而是上线前必须验证的路径。










