关于那消失的 8 小时:Axios 与数据库 datetime 的合谋

关于那消失的 8 小时:Axios 与数据库 datetime 的合谋

西街长安
2026-02-07 / 0 评论 / 7 阅读 / 正在检测是否收录...

说实话,盯着代码看时差,比调 Bug 累多了。

本来本地跑得好好的,17:00 点的数据存进数据库再取出来,直接变成了凌晨 01:00。这种 8 小时的凭空“瞬移”,常让我在屏幕前怀疑人生。

如果你也踩过这个坑,别急着在前端手动 +8,那只会让逻辑变得更乱。这事儿得从头捋。

自动转换的“冷箭”

讲真,很多人觉得 Axios 是原样传输,其实它调了 JSON.stringify

当你的对象里包含 Date 类型时,JS 原型链里的 .toJSON() 方法会自动激活,效果等同于 .toISOString()。不管你本地电脑是什么时区,它都会被强行转成 UTC 零时区,结尾带个明显的 “Z”

  • 本地: 2026-02-07 17:00 (GMT+8)
  • 传给后端时: "2026-02-07T09:00:00.000Z"

这个“Z”,就是一切混乱的开端。


数据库的“失忆症”

后端接收到带“Z”的字符串,解析为 C# 的 DateTime(Kind 为 Utc)时还没出问题。麻烦出在写入 SQL Server 或 MySQL 的 datetime 字段时。

datetime 就像一个只会记数字的记事本。 它只记下了 2026-02-07 09:00:00,至于时区,它根本没地方存。

读取时,噩梦闭环了:

  1. 后端读回数字,因为没有时区信息,C# 默认它为 Unspecified(未指定)。
  2. 回传给前端时,JSON 变成了没有“Z”的字符串。
  3. 浏览器看到没后缀的 ISO 字符串,默认按本地时间解析

于是,原本是 UTC 的 9 点,被当作了本地的 9 点。这就是消失的 8 小时。


别再修补了,直接换零件

别去纠结怎么计算时差。与其在业务代码里打补丁,不如从数据定义上直接解决。

类型存储逻辑读取结果
DateTime只存数字,丢弃偏移量时区全靠猜,极易出错
DateTimeOffset存数字 + 偏移量(如 +00:00)原生支持时区,两端对齐

最终建议:
如果你不想改业务代码,最快的方法就是把数据库字段改成 DateTimeOffset。你会发现数据库里多出了 +00:00 的后缀,前端解析时再也不会产生“时空错位”。

如果你非要守着 datetime 不放,那后端查出来后,必须手动执行 DateTime.SpecifyKind(time, DateTimeKind.Utc) 再返回,否则这锅你永远背不完。

3

评论 (0)

取消