| 特性 | java.util.Date | java.sql.Date |
|---|---|---|
| 套件 | java.util | java.sql |
| 精度 | 毫秒 (日期 + 時間) | 天 (僅日期,時間分量被正規化為 00:00:00) |
| 繼承 | Object | extends java.util.Date |
| 用途 | 通用日期時間處理 | JDBC DATE 類型映射、資料庫交互 |
| 構造器 | Date(), Date(long ms) | Date(int year, int month, int day) @Deprecated, Date(long ms) |
| toString 格式 | dow mon dd hh:mm:ss zzz yyyy | yyyy-MM-dd |
JDBC 規範定義三種時間類型對應 SQL 標準:
java.sql.Date → SQL DATE (年月日)java.sql.Time → SQL TIME (時分秒)java.sql.Timestamp → SQL TIMESTAMP (年月日時分秒毫秒/奈秒)java.sql.Date 繼承 java.util.Date 但強制將時分秒毫秒歸零,確保資料庫 DATE 欄位不存時間資訊。
java.util.Date utilDate = new java.util.Date(); // 當前日期時間
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime()); // 截取日期部分
// 注意:若 utilDate 為 2024-06-15 14:30:00.123
// sqlDate 將為 2024-06-15 (00:00:00.000 本地時區)
java.sql.Date sqlDate = java.sql.Date.valueOf("2024-06-15");
java.util.Date utilDate = sqlDate; // 向上轉型,時間為 00:00:00
// 方式一:valueOf (最簡單,嚴格要求 yyyy-MM-dd)
java.sql.Date sqlDate = java.sql.Date.valueOf("2024-06-15");
// 方式二:LocalDate → sql.Date (Java 8+ 推薦)
java.time.LocalDate localDate = java.time.LocalDate.parse("2024-06-15");
java.sql.Date sqlDate = java.sql.Date.valueOf(localDate);
// 方式三:SimpleDateFormat → util.Date → sql.Date (舊版)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date utilDate = sdf.parse("2024-06-15");
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
// 方式一:toString() 直接輸出 yyyy-MM-dd
String str = sqlDate.toString(); // "2024-06-15"
// 方式二:LocalDate 格式化 (Java 8+)
String formatted = sqlDate.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
// 方式三:SimpleDateFormat (舊版)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String formatted = sdf.format(sqlDate);
// 同一個瞬間,不同時區的 "日期" 可能不同!
// 假設 UTC 時間 2024-06-15 02:00:00
// 時區 UTC+8 (北京) -> 日期 2024-06-15
// 時區 UTC-5 (紐約) -> 日期 2024-06-14
// java.sql.Date 建構子使用「系統預設時區」截取日期
java.util.Date moment = ...; // 某個 Instant
java.sql.Date sqlDate = new java.sql.Date(moment.getTime()); // 依賴 JVM 時區
// 跨時區應用:必須明確指定時區
// 錯誤:new java.sql.Date(moment.getTime()) // 系統時區
// 正確:使用 Java 8+ java.time
ZonedDateTime zdt = moment.toInstant().atZone(ZoneId.of("Asia/Shanghai"));
java.sql.Date correctDate = java.sql.Date.valueOf(zdt.toLocalDate());
| 舊類型 | 現代替代 | 轉換橋樑 |
|---|---|---|
| java.util.Date | java.time.Instant / ZonedDateTime | Date.toInstant(), Date.from(instant) |
| java.sql.Date | java.time.LocalDate | Date.valueOf(localDate), sqlDate.toLocalDate() |
| java.sql.Time | java.time.LocalTime | Time.valueOf(localTime), sqlTime.toLocalTime() |
| java.sql.Timestamp | java.time.LocalDateTime / Instant | Timestamp.from(instant), ts.toInstant() |