MySQL 與 JVM 中的時區(qū)問題
時區(qū)是我們在開發(fā)中經(jīng)常需要考慮的一個問題,因為時間的概念對于很多業(yè)務邏輯都非常重要。MySQL 和 JVM 是我們常用的兩種技術,它們之間的時區(qū)問題也是我們需要關注的。
MySQL 中的時區(qū)
MySQL 在存儲時間類型數(shù)據(jù)時,可以為每個表設置時區(qū),也可以設置全局時區(qū)。全局時區(qū)設置可以使用以下命令:
SET GLOBAL time_zone = 'Asia/Shanghai';
而對于每張表,我們可以在定義表時指定時間類型字段的時區(qū),如下:
CREATE TABLE foo ( id INT, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ENGINE=InnoDB ROW_FORMAT=COMPACT COMMENT='測試用的表' TIME_ZONE='+03:00';
JVM 中的時區(qū)
Java 中有一個類叫做 TimeZone,可以表示一個時區(qū)。在 JRE 中,我們默認使用的是系統(tǒng)時區(qū)。但是在有些情況下,我們需要設置 JVM 的時區(qū),可以使用以下參數(shù):
-Duser.timezone=Asia/Shanghai
MySQL 和 JVM 中的時區(qū)怎么協(xié)調?
在項目中,我們使用 JDBC 連接 MySQL 數(shù)據(jù)庫時,Java 中的時間高精度類型 Timestamp 和 MySQL 數(shù)據(jù)庫中的時間類型 TIMESTAMP 對應,兩者都有自己的時區(qū)偏移。當我們使用 SELECT 查詢時,在獲取時間類型字段時,JDBC 會自動將其轉換為 Java 的 Timestamp 類型,同時會將這個時間從 MySQL 的時區(qū)偏移轉換為 UTC 時間。因此,我們在比較時間時,需要先將 Java 的時間對象轉換為 UTC 時間后再進行比較。
Java 代碼示例:
// 獲取當前時間 Timestamp ts = new Timestamp(System.currentTimeMillis()); // 轉換為 UTC 時間 ts.setTime(ts.getTime() - TimeZone.getDefault().getRawOffset());