技术科普

数据库怎么存时间?DATETIME与TIMESTAMP的区别

数据库中的时间字段如何存储,直接影响系统在跨时区场景下的正确性。不同数据库、不同字段类型的行为差异很大。

MySQL:DATETIME与TIMESTAMP

这是最常被混淆的一对:

  • DATETIME:存储字面值,不随时区变化。写入什么就存什么,取出也不变。范围大(1000–9999年)
  • TIMESTAMP:内部以UTC存储,写入和读取时按会话时区转换。范围较小(约1970–2038年)

举例:会话时区为+08:00时写入 2027-08-28 12:00:00 到 TIMESTAMP,实际存的是UTC的04:00;换成UTC会话查询,显示 2027-08-28 04:00:00。

PostgreSQL:timestamp与timestamptz

  • timestamp(without time zone):不带时区,存字面值
  • timestamptz(with time zone):按UTC存储,显示时转会话时区

PostgreSQL官方推荐使用 timestamptz。

时区处理的关键问题

  • 会话时区(session timezone)会影响TIMESTAMP类的读写结果
  • 连接池中不同连接的会话时区可能不一致,导致数据混乱
  • 跨夏令时写入TIMESTAMP可能引发歧义

最佳实践

  • 统一用UTC存储:应用层统一以UTC写入
  • 用带时区的类型:PostgreSQL用timestamptz,MySQL视需求选择并统一
  • 固定会话时区:如MySQL设置 time_zone = '+00:00'
  • 展示层再转本地时间:由前端或业务层按用户时区格式化

结语

数据库时间存储的核心是明确“存的是绝对时刻还是字面时间”。选对类型、统一时区,才能避免跨时区数据出错。