首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 與 Java 時間類型對應完整指南:DATE、DATETIME、TIMESTAMP 映射與實戰測試

     編輯:MySQL 綜合教學

MySQL 時間類型與 Java JDBC 類型的正確對應,是避免資料截斷、時區偏移、精度遺失的關鍵。本文系統整理類型對應表、儲存範圍差異、插入查詢實戰代碼與最佳實踐。

類型對應總覽表

MySQL 類型Java 類型 (java.sql)儲存範圍精度/特性
DATEjava.sql.Date1000-01-01 ~ 9999-12-31僅日期,無時間元件
DATETIMEjava.sql.Timestamp1000-01-01 00:00:00 ~ 9999-12-31 23:59:59日期+時間,無時區資訊
TIMESTAMPjava.sql.Timestamp1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC自動轉換時區,受 2038 年問題影響
TIMEjava.sql.Time-838:59:59 ~ 838:59:59僅時間,可表示持續時間
YEARjava.sql.Date1901 ~ 2155僅年份,MySQL 8.0 已棄用 YEAR(2)

關鍵差異深度解析

DATE:純日期儲存

  • 僅保留年月日,插入含時間的值會自動截斷時間部分
  • 支援字串格式 'YYYY-MM-DD' 與數字格式 YYYYMMDD 插入
  • Java 端用 ResultSet.getDate() 取得 java.sql.Date

DATETIME vs TIMESTAMP:核心差異

特性DATETIMETIMESTAMP
儲存空間8 bytes (MySQL 5.6.4+)4 bytes
時區感知否,原樣儲存是,寫入轉 UTC,讀出轉會話時區
範圍年份 1000-99991970-2038 (32-bit 限制)
預設值無可設 CURRENT_TIMESTAMP 自動更新
適用場景生日、歷史事件、排程時間建立/更新時間戳、跨時區應用

實戰測試代碼 (JDBC)

public void testDateTypes() throws SQLException {
    Connection conn = DriverManager.getConnection(
        "jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Taipei",
        "root", "password");
    
    try (Statement stmt = conn.createStatement()) {
        // 建立測試表
        stmt.execute("DROP TABLE IF EXISTS time_test");
        stmt.execute("CREATE TABLE time_test (" +
            "id INT AUTO_INCREMENT PRIMARY KEY, " +
            "dt_date DATE, " +
            "dt_datetime DATETIME, " +
            "dt_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " +
            "dt_time TIME, " +
            "dt_year YEAR" +
        ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
        
        // 插入測試資料
        String sql = "INSERT INTO time_test (dt_date, dt_datetime, dt_time, dt_year) VALUES " +
            "('2024-01-15', '2024-01-15 14:30:45', '14:30:45', 2024), " +
            "(20240115, 20240115143045, 143045, 2024)";
        stmt.executeUpdate(sql);
        
        // 查詢驗證
        ResultSet rs = stmt.executeQuery("SELECT * FROM time_test");
        while (rs.next()) {
            System.out.println("DATE: " + rs.getDate("dt_date"));
            System.out.println("DATETIME: " + rs.getTimestamp("dt_datetime"));
            System.out.println("TIMESTAMP: " + rs.getTimestamp("dt_timestamp"));
            System.out.println("TIME: " + rs.getTime("dt_time"));
            System.out.println("YEAR: " + rs.getDate("dt_year")); // YEAR 映射為 Date
        }
    }
}

常見坑點與解決方案

  1. 時區不一致導致 TIMESTAMP 偏移:JDBC URL 加入 serverTimezone=Asia/Taipei (或 UTC)
  2. DATE 插入數字格式補零問題:2024115 會被解析為 2024-01-15,建議統一用字串格式
  3. YEAR 類型在 MySQL 8.0+ 行為變更:YEAR(2) 已移除,統一為 4 位數
  4. java.util.Date vs java.sql.Date:JDBC 專用 java.sql.* 類別,避免用 java.util.Date 直接存取
  5. 2038 年問題:長期專案避免用 TIMESTAMP,改用 DATETIME 或 BIGINT 存 Unix 毫秒數

最佳實踐建議

  • 應用層統一使用 java.time.LocalDateTime (Java 8+),轉換為 java.sql.Timestamp 寫入
  • 資料庫連線池設定 connectionInitSql=SET time_zone='+08:00' 固定會話時區
  • 建表時明確指定 DEFAULT CHARSET=utf8mb4 避免字符集問題
  • 重要時間欄位加上索引,但避免在 WHERE 條件對時間欄位做函數運算
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved