从MYSQL数据库获取到的时间与当前时间不一致问题解决

博客指出查询MySQL数据库时间与当前时间相差较大,原因是名为CST的时区很混乱,Java会误认时区,导致最终结果相差13或14个小时。解决办法是明确指定数据库时区,如设置参数或修改my.cnf文件,操作后需重启服务器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查询数据库时间发现与当前时间差别很大,相差十几个小时

查询数据库时间:

select now() --yyyy-MM-dd HH:mm:ss

 

select sysdate()  --yyyy-MM-dd HH:mm:ss

 

select current_date  --yyyy-MM-dd

 

Linux下进入mysql客户端

1、连接到本机上的MYSQL,一般可以直接键入命令: mysql -uroot -p1。

回车后提示你输密码,如果刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中了,MYSQL的提示符是:mysql>

 

2、连接到远程主机上的MySQL的命令是:mysql -h10.0.0.1 -uroot -p1231。

假设远程主机的IP为:10.0.0.1,用户名为root,密码为123。则键入以下命令:

mysql -h10.0.0.1 -uroot -p1231

(注:u与root可以不用加空格,其它也一样)

3、退出MySQL的命令是:exit (回车)。

 

在执行set global time_zone = '+08:00';与set time_zone = '+08:00';后问题得到解决,此方式不需要重启Mysql!

 

修改完毕后登录到 MySQL 服务器验证这两个值:show variables like '%time_zone%';

原因:

名为 CST 的时区是一个很混乱的时区,在与 MySQL 协商会话时区时,Java 会误以为是 CST -0500,而非 CST +0800。

CST 时区

名为 CST 的时区是一个很混乱的时区,有四种含义:

美国中部时间 Central Standard Time (USA) UTC-06:00

澳大利亚中部时间 Central Standard Time (Australia) UTC+09:30

中国标准时 China Standard Time UTC+08:00

古巴标准时 Cuba Standard Time UTC-04:00

今天是“4月28日”。为什么提到日期?因为美国从“3月11日”至“11月7日”实行夏令时,美国中部时间改为 UTC-05:00,与 UTC+08:00 相差 13 小时。

 

Timestamp 被转换为会话时区的时间字符串了。问题到此已然明晰:

  1. JDBC 误认为会话时区在 CST-5
  2. JBDC 把 Timestamp+0 转为 CST-5 的 String-5
  3. MySQL 认为会话时区在 CST+8,将 String-5 转为 Timestamp-13

最终结果相差 13 个小时!如果处在冬令时还会相差 14 个小时!

解决办法也很简单,明确指定 MySQL 数据库的时区,不使用引发误解的 CST:

mysql> set global time_zone = '+08:00';

Query OK, 0 rows affected (0.00 sec)

mysql> set time_zone = '+08:00';

Query OK, 0 rows affected (0.00 sec)

或者修改 my.cnf 文件,在 [mysqld] 节下增加 default-time-zone = '+08:00'。

修改时区操作影响深远,需要重启 MySQL 服务器,建议在维护时间进行。

<think>我们需要回答MySQL获取当前时间的函数,并给出示例代码解释。然后提出相关问题。 回答流程:先回答问题,给出解释,然后代码示例(如果有必要),最后提出相关问题MySQL获取当前时间的函数主要有以下几个: 1. NOW():返回当前的日期时间,格式为'YYYY-MM-DD HH:MM:SS' 或 'YYYYMMDDHHMMSS',具体取决于函数使用的上下文(字符串或数字)。 2. CURDATE():返回当前日期,格式为'YYYY-MM-DD' 或 'YYYYMMDD'。 3. CURTIME():返回当前时间,格式为'HH:MM:SS' 或 'HHMMSS'。 4. CURRENT_DATE() 或 CURRENT_DATE:CURDATE()相同。 5. CURRENT_TIME() 或 CURRENT_TIME:CURTIME()相同。 6. CURRENT_TIMESTAMP() 或 CURRENT_TIMESTAMP:NOW()相同。 7. SYSDATE():返回函数执行时的时间NOW()同,NOW()返回语句开始执行的时间。 8. UTC_DATE():返回当前UTC日期。 9. UTC_TIME():返回当前UTC时间。 10. UTC_TIMESTAMP():返回当前UTC日期时间。 下面我们通过示例代码展示这些函数的用法。</think># MySQL 获取当前时间的函数详解 在 MySQL 中,有多种函数可以获取当前时间或日期,每种函数返回的时间精度格式有所同。以下是全面的函数列表、使用场景示例: ## 核心时间函数对比 | 函数 | 返回类型 | 格式示例 | 精度 | 是否带时区 | |------|----------|----------|------|------------| | `NOW()` | DATETIME | 2023-10-15 14:30:45 | 微秒 | 会话时区 | | `CURRENT_TIMESTAMP()` | DATETIME | 2023-10-15 14:30:45 | 微秒 | 会话时区 | | `SYSDATE()` | DATETIME | 2023-10-15 14:30:45 | 微秒 | 系统时区 | | `CURDATE()` | DATE | 2023-10-15 | 天 | 会话时区 | | `CURRENT_DATE()` | DATE | 2023-10-15 | 天 | 会话时区 | | `CURTIME()` | TIME | 14:30:45 | 微秒 | 会话时区 | | `CURRENT_TIME()` | TIME | 14:30:45 | 微秒 | 会话时区 | | `UTC_TIMESTAMP()` | DATETIME | 2023-10-15 06:30:45 | 微秒 | UTC | | `UTC_DATE()` | DATE | 2023-10-15 | 天 | UTC | | `UTC_TIME()` | TIME | 06:30:45 | 微秒 | UTC | | `UNIX_TIMESTAMP()` | INT | 1697365845 | 秒 | UTC | ## 详细函数说明代码示例 ### 1. 获取完整日期时间 ```sql -- 获取当前日期时间(会话时区) SELECT NOW(); -- 2023-10-15 14:30:45.123456 SELECT CURRENT_TIMESTAMP(); -- NOW() 相同 -- 获取系统时间(操作系统时区) SELECT SYSDATE(); -- 2023-10-15 14:30:45.123456 -- 获取 UTC 时间 SELECT UTC_TIMESTAMP(); -- 2023-10-15 06:30:45.123456 ``` ### 2. 获取日期部分 ```sql -- 获取当前日期 SELECT CURDATE(); -- 2023-10-15 SELECT CURRENT_DATE(); -- CURDATE() 相同 SELECT CURRENT_DATE; -- 括号可省略 -- 获取 UTC 日期 SELECT UTC_DATE(); -- 2023-10-15 ``` ### 3. 获取时间部分 ```sql -- 获取当前时间 SELECT CURTIME(); -- 14:30:45.123456 SELECT CURRENT_TIME(); -- CURTIME() 相同 SELECT CURRENT_TIME; -- 括号可省略 -- 获取 UTC 时间 SELECT UTC_TIME(); -- 06:30:45.123456 ``` ### 4. 获取时间戳 ```sql -- UNIX 时间戳(秒级) SELECT UNIX_TIMESTAMP(); -- 1697365845 -- 毫秒级时间戳(MySQL 8.0+) SELECT ROUND(UNIX_TIMESTAMP(CURTIME(6)) * 1000); -- 1697365845123 -- 微秒级时间戳(MySQL 8.0+) SELECT CAST(NOW(6) AS DECIMAL(20,6)) * 1000000; -- 1697365845123456 ``` ### 5. 带精度的函数(MySQL 5.6.4+) 所有时间函数都支持指定小数秒精度(0-6): ```sql -- 指定毫秒精度 SELECT NOW(3); -- 2023-10-15 14:30:45.123 SELECT CURTIME(3); -- 14:30:45.123 -- 指定微秒精度 SELECT NOW(6); -- 2023-10-15 14:30:45.123456 SELECT SYSDATE(6); -- 2023-10-15 14:30:45.123456 ``` ## 高级用法示例 ### 1. 在表结构中设置默认时间戳 ```sql CREATE TABLE orders ( id INT PRIMARY KEY AUTO_INCREMENT, order_date DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间 updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 自动更新时间 due_date DATE DEFAULT (CURRENT_DATE + INTERVAL 30 DAY) -- 30天后到期 ); -- 插入数据时自动设置时间 INSERT INTO orders (id) VALUES (1); SELECT * FROM orders; /* +----+---------------------+---------------------+------------+ | id | order_date | updated_at | due_date | +----+---------------------+---------------------+------------+ | 1 | 2023-10-15 14:35:00 | 2023-10-15 14:35:00 | 2023-11-14 | +----+---------------------+---------------------+------------+ */ ``` ### 2. 时间计算比较 ```sql -- 计算时间SELECT TIMEDIFF(NOW(), '2023-10-15 12:00:00') AS time_diff, DATEDIFF(CURDATE(), '2023-10-01') AS days_diff; -- 时间范围查询(今天内的订单) SELECT * FROM orders WHERE order_date >= CURDATE() AND order_date < CURDATE() + INTERVAL 1 DAY; -- 使用时间戳过滤(最近30分钟的数据SELECT * FROM user_activity WHERE activity_time > NOW() - INTERVAL 30 MINUTE; ``` ### 3. 格式化时间输出 ```sql SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日 %H:%i:%s') AS formatted_cn, -- 2023年10月15日 14:40:22 DATE_FORMAT(UTC_TIMESTAMP(), '%b %d, %Y %h:%i %p') AS formatted_us; -- Oct 15, 2023 02:40 PM ``` ### 4. 时区转换(MySQL 8.0+) ```sql -- 将会话时区转换为UTC SET time_zone = '+00:00'; SELECT NOW(); -- UTC时间 -- 将时间转换为特定时区 SELECT CONVERT_TZ(NOW(), @@session.time_zone, 'America/New_York') AS ny_time, CONVERT_TZ(NOW(), @@session.time_zone, 'Asia/Shanghai') AS sh_time; ``` ## 性能注意事项 1. **函数调用次数**:`NOW()` 在 SQL 语句中多次调用返回相同值,而 `SYSDATE()` 每次调用都获取新值 ```sql SELECT NOW(), SLEEP(2), NOW(); -- 两个 NOW() 值相同 SELECT SYSDATE(), SLEEP(2), SYSDATE(); -- 两个 SYSDATE() 值相差2秒 ``` 2. **索引使用**:避免在 WHERE 子句中对时间列使用函数 ```sql -- 低效(无法使用索引): SELECT * FROM orders WHERE DATE(order_date) = CURDATE(); -- 高效(可使用索引): SELECT * FROM orders WHERE order_date >= CURDATE() AND order_date < CURDATE() + INTERVAL 1 DAY; ``` 3. **存储类型选择**: - 需要时间部分:使用 `DATETIME` - 只需要日期:使用 `DATE`(节省存储空间) - 需要时区信息:MySQL 8.0+ 使用 `TIMESTAMP`(自动转换为UTC存储) ## 最佳实践总结 1. **一致性**:在整个项目中统一使用 `CURRENT_TIMESTAMP` 或 `NOW()` 2. **时区管理**: - 存储时使用UTC时间:`UTC_TIMESTAMP()` - 显示时转换为本地时间:`CONVERT_TZ()` 3. **精度控制**:根据业务需求指定适当的时间精度 4. **自动更新**:利用 `ON UPDATE CURRENT_TIMESTAMP` 自动维护更新时间 5. **性能优化**:避免在WHERE子句中使用时间函数处理列值
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值