MySQL 的时区问题

发布于 2025-08-22 17:15:49

MySQL 的 CURRENT_TIMESTAMP 显示不准确,通常是由于 时区设置不正确系统时间与 MySQL 时间不一致 导致的。下面我将从多个方面帮你排查和解决这个问题。


🔍 一、问题表现

  • 使用 NOW()CURRENT_TIMESTAMP 获取的时间与实际时间不符(快/慢几个小时)。
  • 存储的时间与你所在的时区(如北京时间)不一致。
  • 时间相差 8 小时(常见于 UTC 和 CST 时区混淆)。

✅ 二、解决方案

✅ 1. 检查当前 MySQL 时间和系统时间

-- 查看 MySQL 当前时间
SELECT NOW();
SELECT CURRENT_TIMESTAMP;

-- 查看 MySQL 时区设置
SELECT @@global.time_zone, @@session.time_zone;
# 在 Linux 终端查看系统时间
date
timedatectl
✅ 正常情况:NOW() 应与系统时间一致。

✅ 2. 设置 MySQL 时区为东八区(CST/Asia/Shanghai)

方法一:修改 MySQL 配置文件(推荐)

编辑 MySQL 配置文件(通常为 /etc/my.cnf/etc/mysql/my.cnf):

[mysqld]
default-time-zone='+8:00'
# 或使用命名时区(需时区表已加载)
# default-time-zone='Asia/Shanghai'
⚠️ 修改后需重启 MySQL:
sudo systemctl restart mysql
# 或
sudo service mysql restart

方法二:动态设置(临时生效)

-- 设置全局时区
SET GLOBAL time_zone = '+8:00';

-- 设置当前会话时区
SET time_zone = '+8:00';
✅ 验证是否生效:
SELECT NOW(); -- 应显示北京时间

✅ 3. 使用命名时区(更规范)

如果希望使用标准时区名称(如 Asia/Shanghai):

步骤 1:加载时区表

# 在终端执行(Linux)
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
这会将系统时区信息导入 MySQL 的 mysql.time_zone* 表中。

步骤 2:设置时区

[mysqld]
default-time-zone='Asia/Shanghai'

或动态设置:

SET GLOBAL time_zone = 'Asia/Shanghai';

✅ 4. 开发中建议:统一使用 UTC 存储,前端转换

📌 推荐做法:

  • 数据库存储使用 UTC 时间
  • 应用层或前端根据用户时区显示本地时间
-- 存储 UTC 时间
INSERT INTO logs(created_at) VALUES(UTC_TIMESTAMP());

-- 查询时转换为北京时间
SELECT CONVERT_TZ(created_at, 'UTC', 'Asia/Shanghai') FROM logs;
✅ 优点:避免时区混乱,适合多时区系统。

✅ 5. 检查操作系统时区是否正确

# 查看当前系统时区
timedatectl

# 设置为上海时区(Linux)
sudo timedatectl set-timezone Asia/Shanghai
MySQL 依赖系统时区,系统时间不准会影响 MySQL。

🛠️ 常见问题排查清单

检查项命令/操作正确值示例
系统时间dateFri Aug 22 12:00:00 CST 2025
MySQL 当前时间SELECT NOW();2025-08-22 12:00:00
MySQL 全局时区SELECT @@global.time_zone;+08:00Asia/Shanghai
MySQL 会话时区SELECT @@session.time_zone;同上
配置文件设置my.cnfdefault-time-zone+8:00Asia/Shanghai

✅ 总结

问题原因解决方案
时区未设置my.cnf 中设置 default-time-zone='+8:00'
使用 UTC 时间动态设置 SET time_zone = '+8:00';
时区名称不支持执行 mysql_tzinfo_to_sql 加载时区表
系统时间不准使用 timedatectl set-timezone Asia/Shanghai

✅ 最终建议

# my.cnf
[mysqld]
default-time-zone='Asia/Shanghai'
log_timestamps='SYSTEM'  # 日志时间也用本地时区

重启 MySQL 后执行:

SELECT NOW(); -- 应显示正确北京时间

0 条评论

发布
问题