MySQL時間類型與Java日期時間類對應關系示例詳解
一、MySQL 時間類型與 Java 類型對應關系
| MySQL 類型 | 范圍/描述 | Java 對應類型 | 精度級別 |
|---|---|---|---|
| ??DATE?? | '1000-01-01' - '9999-12-31' | java.time.LocalDate | 日期 |
| ??TIME?? | '-838:59:59' - '838:59:59' | java.time.LocalTime | 時間 |
| ??DATETIME?? | '1000-01-01 00:00:00' - '9999-12-31 23:59:59' | java.time.LocalDateTime | 毫秒/微秒 |
| ??TIMESTAMP?? | '1970-01-01 00:00:01' - '2038-01-19 03:14:07' | java.time.Instantjava.sql.Timestamp | 秒/毫秒 |
| ??YEAR?? | 1901 - 2155 | java.time.Yearjava.lang.Integer | 年 |
二、JDBC 操作映射關系
1. 從數(shù)據(jù)庫讀取數(shù)據(jù)
try (ResultSet rs = stmt.executeQuery("SELECT * FROM time_table")) {
while (rs.next()) {
LocalDate date = rs.getObject("date_column", LocalDate.class);
LocalTime time = rs.getObject("time_column", LocalTime.class);
LocalDateTime dateTime = rs.getObject("datetime_column", LocalDateTime.class);
Instant timestamp = rs.getObject("ts_column", Instant.class);
}
}2. 向數(shù)據(jù)庫寫入數(shù)據(jù)
PreparedStatement ps = conn.prepareStatement(
"INSERT INTO time_table (date_column, time_column, datetime_column, ts_column) " +
"VALUES (?, ?, ?, ?)");
ps.setObject(1, LocalDate.now());
ps.setObject(2, LocalTime.now());
ps.setObject(3, LocalDateTime.now());
ps.setObject(4, Instant.now());
ps.executeUpdate();三、MySQL 時間類型詳細對比
| ??特性?? | DATE | TIME | DATETIME | TIMESTAMP | YEAR |
|---|---|---|---|---|---|
| ??時區(qū)敏感?? | 否 | 否 | 否 | ??是?? | 否 |
| ??自動初始化?? | 否 | 否 | 否 | ??是?? | 否 |
| ??自動更新?? | 否 | 否 | 否 | ??是?? | 否 |
| ??存儲空間(字節(jié))?? | 3 | 3 | 5-8 | 4 | 1 |
| ??微秒精度支持?? | - | MySQL 5.6+ | MySQL 5.6+ | MySQL 5.6.4+ | - |
| ??2038年限制?? | 無 | 無 | 無 | ??有?? (2038年) | 無 |
四、微秒精度處理(MySQL 5.6+)
// Java 端處理微秒(MySQL DATETIME(6))
LocalDateTime ldt = LocalDateTime.now()
.withNano(456000000); // 456毫秒
// MySQL 創(chuàng)建表
CREATE TABLE events (
event_time DATETIME(6) // 支持微秒級精度
);五、時區(qū)處理最佳實踐
1. 時間存儲策略
// 寫入統(tǒng)一使用 UTC 時間
ps.setObject(4, Instant.now()); // UTC 時間戳
// 讀取時轉換為本地時間
Instant dbTime = rs.getObject("event_time", Instant.class);
ZonedDateTime localTime = dbTime.atZone(ZoneId.systemDefault());2. MySQL 服務器配置
-- 檢查時區(qū)設置 SELECT @@global.time_zone, @@session.time_zone; -- 推薦設置為 UTC SET GLOBAL time_zone = '+00:00';
六、特殊場景處理方案
1. 日期范圍統(tǒng)計
LocalDate start = LocalDate.of(2023, 1, 1);
LocalDate end = LocalDate.of(2023, 12, 31);
PreparedStatement ps = conn.prepareStatement(
"SELECT * FROM orders WHERE order_date BETWEEN ? AND ?");
ps.setObject(1, start);
ps.setObject(2, end);2. 時間區(qū)間查詢(TIMESTAMP + 時區(qū))
Instant startInstant = ZonedDateTime.of(
2023, 5, 1, 0, 0, 0, 0,
ZoneId.of("Asia/Shanghai")).toInstant();
PreparedStatement ps = conn.prepareStatement(
"SELECT * FROM transactions WHERE create_time >= ?");
ps.setObject(1, startInstant);3. 時間間隔計算(Java 端處理)
LocalDateTime orderTime = rs.getObject("order_time", LocalDateTime.class);
LocalDateTime deliveryTime = rs.getObject("delivery_time", LocalDateTime.class);
Duration interval = Duration.between(orderTime, deliveryTime);
System.out.printf("配送耗時: %.1f小時", interval.toMinutes() / 60.0);七、傳統(tǒng) java.sql 類替代方案
| 傳統(tǒng)類 | Java 8+ 替代方案 | 使用場景 |
|---|---|---|
java.sql.Date | LocalDate | 只處理日期部分 |
java.sql.Time | LocalTime | 只處理時間部分 |
java.sql.Timestamp | Instant 或 LocalDateTime | 帶時區(qū)的時間戳/本地日期時間 |
轉換示例:
// 傳統(tǒng)轉現(xiàn)代
Timestamp ts = rs.getTimestamp("create_time");
LocalDateTime ldt = ts.toLocalDateTime();
// 現(xiàn)代轉傳統(tǒng)
LocalDateTime now = LocalDateTime.now();
Timestamp ts = Timestamp.valueOf(now);八、時區(qū)轉換流程圖
graph LR
A[業(yè)務系統(tǒng)時間\nLocalDateTime] -->|應用時區(qū)| B[JVM 默認時區(qū)]
B -->|轉換為UTC| C[Instant/UTC時間]
C -->|存儲至MySQL| D[TIMESTAMP列]
D -->|讀取為Instant| E[Java Instant類型]
E -->|轉換至目標時區(qū)| F[用戶時區(qū)顯示]九、常見問題解決方案
??時區(qū)錯亂問題??
// 明確設置JVM時區(qū)(啟動參數(shù)) -Duser.timezone=Asia/Shanghai // JDBC連接指定時區(qū) jdbc:mysql://localhost/db?serverTimezone=Asia/Shanghai
??2038年TIMESTAMP溢出??
- 在 MySQL 8.0 升級 TIMESTAMP 到 8 字節(jié)存儲
- 將 TIMESTAMP 改為 DATETIME 類型
??微秒精度丟失??
// 數(shù)據(jù)庫指定精度(DATETIME(6)) LocalDateTime ldt = LocalDateTime.now().withNano(123456000);
??跨時區(qū)同步問題??
- 統(tǒng)一使用 UTC 時間存儲(TIMESTAMP)
- 前端顯示時根據(jù)用戶時區(qū)轉換
總結建議
??類型選擇優(yōu)先級??:
- 日期 →
DATE↔LocalDate - 時間 →
TIME↔LocalTime - 完整時間 →
DATETIME↔LocalDateTime - 跨時區(qū)時間 →
TIMESTAMP↔Instant
- 日期 →
??最佳實踐??:
// 創(chuàng)建表規(guī)范 CREATE TABLE events ( id BIGINT PRIMARY KEY, event_date DATE, -- 日期類數(shù)據(jù) event_time TIME(3), -- 毫秒級時間 start_datetime DATETIME(6), -- 微秒級本地時間 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 帶時區(qū)時間 ); // Java操作規(guī)范 repository.save(new Event( LocalDate.now(), LocalTime.now().truncatedTo(ChronoUnit.MILLIS), LocalDateTime.now().withNano(456000000), Instant.now() ));??重要原則??:
- 前端交互:字符串(ISO 8601格式)
- 業(yè)務層:java.time 類型
- 持久層:直接映射數(shù)據(jù)庫類型
- 存儲時態(tài):統(tǒng)一使用UTC標準時區(qū)
??調試技巧??:
-- MySQL查看實際存儲值 SELECT date_column, UNIX_TIMESTAMP(ts_column) AS timestamp_value, CONVERT_TZ(ts_column, '+00:00', @@session.time_zone) AS local_time FROM time_table;
掌握MySQL和Java時間類型的精確對應關系,是處理國際化應用、財務系統(tǒng)和時效敏感業(yè)務的基礎。遵循UTC存儲、本地化展示的原則,可規(guī)避90%的時區(qū)相關問題。
到此這篇關于MySQL時間類型與Java日期時間類對應關系的文章就介紹到這了,更多相關MySQL時間類型與Java日期時間類內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
MySQL rand函數(shù)實現(xiàn)隨機數(shù)的方法
在mysql中,使用隨機數(shù)寫一個語句能一下更新幾百條MYSQL數(shù)據(jù)嗎?答案是肯定的,使用MySQL rand函數(shù),就可以使現(xiàn)在隨機數(shù)2016-09-09
windows下如何解決mysql secure_file_priv null問題
這篇文章主要介紹了windows下如何解決mysql secure_file_priv null問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
windows下在一臺機器上安裝兩個MYSQL數(shù)據(jù)庫的方法
正常安裝第一個mysql,在控制面板里停止第一個mysql服務,將C:\Program Files\MySQL目錄下的所有目錄和文件copy到另外一個路徑,我這里是copy到E盤2013-10-10
MySQL的MRR(Multi-Range Read)優(yōu)化原理解析
MRR優(yōu)化是MySQL中一種重要的查詢優(yōu)化技術,它通過減少磁盤I/O的隨機性和提高緩存效率,顯著提升了查詢性能,這篇文章主要介紹了MySQL的MRR(Multi-Range Read)優(yōu)化原理詳解,需要的朋友可以參考下2024-08-08
Mysql數(shù)據(jù)庫5.7升級到8.4的實現(xiàn)
很多情況需要升級MySQL的數(shù)據(jù)庫版本,本文主要介紹了Mysql數(shù)據(jù)庫5.7升級到8.4的實現(xiàn),文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-06-06
MySQL切分函數(shù)substring()的具體使用
這篇文章主要介紹了MySQL切分函數(shù)substring()的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-02-02

