⚠️ **缺點**:可變、非執行緒安全、月份 0-based、年份偏移 1900、API 設計混亂。僅維護舊代碼時使用。
import java.util.*;
import java.text.*;
public class LegacyDateTime {
public static void main(String[] args) {
// 1. Date 取得當前
Date now = new Date();
System.out.println("Date.toString(): " + now); // Mon May 20 14:30:00 CST 2024
// 2. DateFormat 格式化 (非執行緒安全!)
DateFormat df1 = DateFormat.getDateInstance(); // 短日期
DateFormat df2 = DateFormat.getDateTimeInstance(); // 日期時間
DateFormat df3 = DateFormat.getTimeInstance(); // 時間
DateFormat df4 = DateFormat.getInstance(); // 短日期時間
System.out.println("預設日期: " + df1.format(now));
System.out.println("預設日期時間: " + df2.format(now));
System.out.println("預設時間: " + df3.format(now));
System.out.println("短格式: " + df4.format(now));
// 3. 自訂格式 (SimpleDateFormat 非執行緒安全)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("自訂: " + sdf.format(now));
// 4. Calendar 取得欄位 (月份 0-based!)
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1; // +1 修正
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY); // 24制
int min = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
System.out.printf("Calendar: %d-%02d-%02d %02d:%02d:%02d%n", year, month, day, hour, min, sec);
}
}
✅ **優點**:不可變、執行緒安全、領域驅動設計、月份 1-based、納秒精度、支援時區/DST。
import java.time.*;
import java.time.format.DateTimeFormatter;
public class ModernDateTime {
public static void main(String[] args) {
// 1. 核心類別取得當前
LocalDate date = LocalDate.now(); // 2024-05-20
LocalTime time = LocalTime.now(); // 14:30:00.123
LocalDateTime dt = LocalDateTime.now(); // 2024-05-20T14:30:00.123
ZonedDateTime zdt = ZonedDateTime.now(); // 2024-05-20T14:30:00.123+08:00[Asia/Taipei]
Instant instant = Instant.now(); // 2024-05-20T06:30:00.123Z (UTC)
// 2. 取得欄位 (直觀、無偏移)
System.out.println("年: " + dt.getYear());
System.out.println("月: " + dt.getMonthValue()); // 5
System.out.println("日: " + dt.getDayOfMonth());
System.out.println("時: " + dt.getHour());
System.out.println("分: " + dt.getMinute());
System.out.println("秒: " + dt.getSecond());
// 3. 格式化 (DateTimeFormatter 執行緒安全,可重用)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println("格式化: " + dt.format(fmt));
// 4. 解析
LocalDateTime parsed = LocalDateTime.parse("2024-12-31 23:59:59", fmt);
// 5. 互相轉換
Instant ins = dt.atZone(ZoneId.systemDefault()).toInstant();
Date legacy = Date.from(ins); // 轉舊 Date
System.out.println("轉 Date: " + legacy);
}
}
| 特性 | Date/Calendar | java.time |
|---|---|---|
| 可變性 | 可變 (setTime, add) | 不可變 (plus/minus 回傳新物件) |
| 執行緒安全 | ❌ SimpleDateFormat 非安全 | ✅ 全部安全 |
| 月份索引 | 0-11 (坑) | 1-12 (直觀) |
| 年份基準 | 1900 (getYear() 已棄用) | 實際年份 |
| 精度 | 毫秒 | 納秒 |
| 時區處理 | TimeZone 混亂 | ZoneId/ZoneOffset 清晰 |
| 格式化類別 | SimpleDateFormat (非安全) | DateTimeFormatter (安全) |
| 舊代碼 | 新代碼 |
|---|---|
| new Date() | Instant.now() / LocalDateTime.now() |
| Calendar.getInstance() | LocalDateTime.now() / ZonedDateTime.now() |
| new SimpleDateFormat("...") | DateTimeFormatter.ofPattern("...") |
| date.getTime() | instant.toEpochMilli() |
| cal.get(Calendar.MONTH)+1 | localDate.getMonthValue() |
| cal.add(Calendar.DAY, 1) | localDate.plusDays(1) |
Java 8 日期時間 API 設計優雅、功能強大,徹底解決舊 API 三大痛點 (可變、非安全、月份偏移)。全面擁抱 `java.time`,享受現代化時間處理體驗。