插入mysql数据库时间相差14个小时

本文介绍在SpringCloud项目中使用MyBatis框架,遇到DateTime类型数据插入MySQL数据库时时间相差14小时的问题及原因。通过调整JDBC驱动版本或在URL中设置serverTimezone参数来解决。

背景:

spring cloud 开发web项目,数据库:mysql 持久性框架:mybatis

问题:

前一段时间遇到这么一个问题:新增数据时,datatime类型的数据插入到mysql数据库后时间相差14个小时(数据库数据比当前时间少14个小时)。

排查:

1、程序在入库前没有做任何特殊处理
2、检查系统时区:CST
3、检查数据库时区:CST(没有修改的话一般都是系统时区)
造成这种问题的原因是因为高版本jdbc导致的问题,高版本的jdbc底层驱动程序对从数据库查询出来的时间用了一个Calender做类型转换,Calender记录中包含的时区导致差了14小时。(引用自:https://www.cnblogs.com/bignode/p/9310893.html)

解决:

有两种方式解决此问题
方式一:在配置文件的jdbc的url上面手动设置了serverTimezone=CST(保持和操作系统和数据库一致的时区,不管哪里的时区只要保持一致就可以喽)
方式二:修改pom文件的spring-boot版本和spring-cloud版本,比如

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Finchley.RC1</spring-cloud.version>
</properties>

这样就自动引入5.1.46版本的jdbc驱动,就不会出现相差14个小时的问题啦

<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子句中使用时间函数处理列值
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值