在 Java 開發中,日期與時間的處理是商業邏輯中不可或缺的核心環節。Java 類庫提供了 Date 與 Calendar 兩大核心類來應對這一需求。雖然 Date 類自 JDK 1.0 起便隨 Java 一同演進,但其早期設計存在諸多不足,導致大部分操作日期組件的方法已被棄用,並轉移至功能更強大、設計更合理的 Calendar 體系中。本文將系統梳理這兩個類的核心用法,並輔以實戰代碼示例,助你輕鬆駕馭時間處理。
java.util.Date 類的主要使命是封裝當前時間戳。其無參構造方法 new Date() 會自動捕捉系統當前毫秒數(自 GMT 1970 年 1 月 1 日 00:00:00 起)。
Date date = new Date(); System.out.println(date.getTime()); // 輸出長整型毫秒數,如 1001803809710
直接打印 Date 對象或調用 getTime() 均返回難以閱讀的長整型數值。要將其轉為人類可讀格式,必須借助格式化工具類 DateFormat 及其子類 SimpleDateFormat。
SimpleDateFormat 允許開發者通過模式字符串精確控制輸出格式。常用模式字母含義如下:
yyyy:四位數年份MM / MMM / MMMM:月份(數字/縮寫/全稱)dd:月中的天數EEEE:星期全稱示例:輸出「星期六-九月-29-2001」格式:
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("EEEE-MMMM-dd-yyyy");
System.out.println(sdf.format(date));
若不想手寫模式,可直接調用 DateFormat.getDateTimeInstance() 獲取預定義風格(SHORT, MEDIUM, LONG, FULL)的格式化器,自動適配運行環境的語言環境:
DateFormat shortFmt = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); DateFormat fullFmt = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); System.out.println(shortFmt.format(date)); // 例:9/29/01 8:44 PM System.out.println(fullFmt.format(date)); // 例:Saturday, September 29, 2001 8:44:45 PM EDT
Calendar 為抽象類,常用其具體子類 GregorianCalendar。它提供了豐富的字段常量(如 YEAR, MONTH, DAY_OF_MONTH, DAY_OF_WEEK 等)及 get()、set()、add() 方法,支援對日期任意組件的讀寫與運算,自動處理閏年、月份天數差異等複雜邏輯。
DateFormat fmt = DateFormat.getDateInstance(DateFormat.FULL);
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(new Date()); // 同步系統時間
System.out.println("系統時間: " + fmt.format(cal.getTime()));
// 將日期調整為本週五
cal.set(GregorianCalendar.DAY_OF_WEEK, GregorianCalendar.FRIDAY);
System.out.println("調整後: " + fmt.format(cal.getTime()));
int count = 0;
while (count < 10) {
cal.add(GregorianCalendar.DAY_OF_MONTH, 7); // 往後推 7 天(下一個週五)
if (cal.get(GregorianCalendar.DAY_OF_MONTH) == 13) {
count++;
System.out.println("第 " + count + " 個週五13號: " + fmt.format(cal.getTime()));
}
}
輸出片段:
系統時間: Saturday, September 29, 2001 調整後: Friday, September 28, 2001 第 1 個週五13號: Friday, September 13, 2002 第 2 個週五13號: Friday, December 13, 2002 ...
System.currentTimeMillis() 或 Instant.now().toEpochMilli()(Java 8+),避免創建 Date 對象開銷。SimpleDateFormat 或 Java 8 DateTimeFormatter,注意線程安全問題(SimpleDateFormat 非線程安全)。Calendar 或 Java 8 LocalDate/LocalDateTime / ZonedDateTime,切勿自行計算毫秒數增減。Date 類中 getYear(), getMonth() 等方法已棄用,嚴禁在新代碼中使用。掌握 Date、Calendar 及格式化類的協作模式,是構建健壯時間敏感型業務系統的基石。隨著 Java 8 引入全新的 java.time 包,建議新項目優先採用 LocalDateTime、ZonedDateTime 等不可變、線程安全的新 API,漸進式替換舊有代碼。