Date 進行字段操作。ThreadLocal 包裝或升級 JDK 8+ java.time 套件。Calendar cal = Calendar.getInstance(); // 默認時區/ Locale
// Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1; // 0-based,需 +1
int day = cal.get(Calendar.DATE); // 或 DAY_OF_MONTH
int hour24 = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); // 1=周日, 2=周一...
Date date = cal.getTime(); // 轉 Date
cal.set(Calendar.YEAR, 2025);
cal.set(2025, 11, 25, 14, 30, 0); // 月份 0-based
cal.setTime(new Date()); // 從 Date 同步
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// yyyy 年, MM 月, dd 日, HH 24時, hh 12時, mm 分, ss 秒
// Date → String
String str = sdf.format(new Date());
// String → Date
try {
Date parsed = sdf.parse("2025-12-25 14:30:00");
} catch (ParseException e) {
// 處理解析失敗
}
💡 線程安全寫法:ThreadLocal<SimpleDateFormat> tl = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, 1); // 明年
cal.add(Calendar.MONTH, -3); // 3 個月前
cal.add(Calendar.DATE, 10); // 10 天後
// 支援所有字段:HOUR, MINUTE, SECOND 等
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d1 = sdf.parse("2025-01-01");
Date d2 = sdf.parse("2025-12-31");
long diffDays = (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24);
System.out.println("間隔 " + diffDays + " 天");
Date d1 = sdf.parse("2025-01-01 10:00:00");
Date d2 = sdf.parse("2025-12-31 10:00:00");
// 1. before / after (最常用)
boolean early = d1.before(d2); // true
boolean late = d2.after(d1); // true
// 2. compareTo (排序/精確比較)
int cmp = d1.compareTo(d2); // -1 (d1d2)
// 3. getTime() 比較毫秒值 (底層邏輯)
long ms1 = d1.getTime();
long ms2 = d2.getTime();
| 坑點 | 錯誤寫法 | 正確寫法 |
|---|---|---|
| 月份 0-based | cal.set(2025, 12, 1) | cal.set(2025, 11, 1) // 12月 |
| 周日為 1 | if (dow == 7) // 周六 | if (dow == Calendar.SATURDAY) |
| SimpleDateFormat 非線程安全 | static final SimpleDateFormat SDF = ... | ThreadLocal 或局部變量 |
| 字符串解析異常未捕獲 | Date d = sdf.parse(str); | try-catch ParseException |
| 直接比較 Date 引用 | d1 == d2 | d1.equals(d2) 或 compareTo |
新專案強烈建議遷移至 java.time:
LocalDate/LocalDateTime:不可變、線程安全、API 清晰。DateTimeFormatter:替代 SimpleDateFormat。Period/Duration:替代手動毫秒運算。ZoneId/ZonedDateTime:完善時區支持。// JDK 8+ 範例
LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plusWeeks(1);
long days = ChronoUnit.DAYS.between(today, nextWeek);
String formatted = today.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));