Docker 容器时区问题:UTC 导致的自然日业务刷新异常
目录
最近将微信小程序后端迁移到 Docker 后,出现了“每日刷新”相关 Bug,例如:
- 每日广告次数未刷新
- 次日仍然沿用前一天状态
排查后发现,问题并不在业务逻辑,而是:
- Docker 容器默认使用 UTC 时区。
而业务中的“每日刷新”逻辑实际上是基于东八区自然日实现的。
例如:
| |
当中国时间已经进入第二天时:
| 中国时间 | UTC 时间 |
|---|---|
| 2026-05-19 00:30 | 2026-05-18 16:30 |
后端仍然认为“还是昨天”,从而导致自然日逻辑整体延迟 8 小时。
最终方案
数据库存储统一使用 UTC
数据库中的 datetime / timestamp 统一存 UTC。
优点:
- 避免时区混乱
- 避免夏令时问题
- 多服务容易统一
前端负责本地化显示
后端返回 UTC:
前端按用户本地时区格式化:
| |
自然日业务明确业务时区
像:
- 每日限额
- 定时刷新
这类逻辑本质上依赖“业务时区”。
对于面向中国用户的服务,直接统一:
| |
通常是最简单稳定的方案。
精简镜像中的 tzdata 问题
如果使用 Alpine / slim 等精简镜像:
则可能需要额外安装:
| |
总结
目前采用的时间处理策略:
| 层级 | 策略 |
|---|---|
| 数据库存储 | UTC |
| 前端显示 | 用户本地时区 |
| 后端 Docker 容器 | TZ=Asia/Shanghai |