java.util.Calendar 是 Java 早期核心日期時間 API,雖然 Java 8 引入了更優雅的 java.time 套件,但大量既有系統仍廣泛使用 Calendar。本文系統整理 Calendar 的核心操作,包含實例化、欄位存取、日期運算、比較與格式化,並附上完整可執行範例。
Calendar.JANUARY = 0,Calendar.DECEMBER = 11。設定或取得月份時需 +1 或 -1。
| 常數 | 值 |
|---|---|
| Calendar.SUNDAY | 1 |
| Calendar.MONDAY | 2 |
| Calendar.TUESDAY | 3 |
| Calendar.WEDNESDAY | 4 |
| Calendar.THURSDAY | 5 |
| Calendar.FRIDAY | 6 |
| Calendar.SATURDAY | 7 |
YEAR、MONTH、DATE(或 DAY_OF_MONTH)HOUR_OF_DAY (24小時制)、MINUTE、SECOND、MILLISECONDDAY_OF_WEEK、DAY_OF_YEAR、WEEK_OF_YEARpackage demo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class CalendarDemo {
public static void main(String[] args) {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
// 1. 取得當前時間
Calendar cal = Calendar.getInstance();
System.out.println("目前時間: " + fmt.format(cal.getTime()));
// 2. 設定特定日期 (兩種方式)
// 方式 A: 透過 Date 物件
try {
Date d = new SimpleDateFormat("yyyy-M-d H:m:s").parse("2013-6-1 13:24:16");
cal.setTime(d);
System.out.println("設定後時間: " + fmt.format(cal.getTime()));
} catch (ParseException e) { e.printStackTrace(); }
// 方式 B: 直接設定欄位 (注意月份 1 = 二月)
cal = Calendar.getInstance();
cal.set(2013, 1, 2, 17, 35, 44); // 2013-02-02 17:35:44
System.out.println("直接設定: " + fmt.format(cal.getTime()));
// 3. 取得各欄位數值
cal = Calendar.getInstance(); // 重置為當前
System.out.println("年份: " + cal.get(Calendar.YEAR));
System.out.println("月份: " + (cal.get(Calendar.MONTH) + 1)); // 需 +1
System.out.println("星期: " + cal.get(Calendar.DAY_OF_WEEK)); // 1=週日
System.out.println("今年第幾天: " + cal.get(Calendar.DAY_OF_YEAR));
System.out.println("本月第幾天: " + cal.get(Calendar.DAY_OF_MONTH));
// 4. 日期時間加減運算 (add 會自動進位)
cal.add(Calendar.HOUR_OF_DAY, 3); // +3小時
System.out.println("3小時後: " + fmt.format(cal.getTime()));
cal.add(Calendar.MINUTE, 15); // +15分鐘
System.out.println("再+15分: " + fmt.format(cal.getTime()));
cal.add(Calendar.MINUTE, -30); // -30分鐘
System.out.println("再-30分: " + fmt.format(cal.getTime()));
// 5. 日期比較 (compareTo)
Calendar calNow = Calendar.getInstance();
Calendar calPast = Calendar.getInstance();
calPast.add(Calendar.HOUR, -5); // 5小時前
System.out.println("過去 vs 現在: " + calPast.compareTo(calNow)); // -1 (過去較小)
calPast.add(Calendar.HOUR, 7); // 現在 +2小時
System.out.println("未來 vs 現在: " + calPast.compareTo(calNow)); // 1 (未來較大)
calPast.add(Calendar.HOUR, -2); // 回到現在
System.out.println("相同時間: " + calPast.compareTo(calNow)); // 0
// 6. 計算兩日期相差天數
Calendar begin = Calendar.getInstance();
begin.set(2023, 0, 1); // 2023-01-01
Calendar end = Calendar.getInstance();
end.set(2023, 0, 10); // 2023-01-10
long diffMillis = end.getTimeInMillis() - begin.getTimeInMillis();
long diffDays = diffMillis / (1000 * 60 * 60 * 24);
System.out.println("相差天數: " + diffDays); // 輸出 9
}
}
| 方法 | 說明 | 範例 |
|---|---|---|
| getInstance() | 取得預設時區/語系的 Calendar 實例 (單例模式) | Calendar cal = Calendar.getInstance(); |
| setTime(Date) | 以 Date 物件設定 Calendar 時間 | cal.setTime(new Date()); |
| set(int field, int value) | 設定單一欄位 | cal.set(Calendar.YEAR, 2025); |
| set(int y, int m, int d, int h, int min, int s) | 一次設定年月日時分秒 | cal.set(2025, 11, 25, 12, 0, 0); |
| get(int field) | 取得欄位數值 | int year = cal.get(Calendar.YEAR); |
| add(int field, int amount) | 欄位加減 (自動處理進位/借位) | cal.add(Calendar.DATE, 7); // 一週後 |
| roll(int field, int amount) | 欄位加減 (不改變較大單位) | cal.roll(Calendar.MONTH, 1); // 月份+1, 年份不變 |
| compareTo(Calendar) | 比較時間先後 (-1/0/1) | cal1.compareTo(cal2); |
| getTimeInMillis() | 取得毫秒時間戳 (長整數) | long ms = cal.getTimeInMillis(); |
| getTime() | 轉換為 java.util.Date 物件 | Date d = cal.getTime(); |
搭配 SimpleDateFormat 進行字串轉換:
// 格式化 Calendar -> String
String str = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(cal.getTime());
// 解析 String -> Calendar
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date d = sdf.parse("2024-12-31");
Calendar cal = Calendar.getInstance();
cal.setTime(d);
} catch (ParseException e) { e.printStackTrace(); }
新專案強烈建議使用 java.time 套件 (LocalDateTime, ZonedDateTime, DateTimeFormatter 等),優點:
若必須維護舊代碼,Calendar 仍是可靠選擇;若可重構,請優先遷移至 java.time。
Calendar 雖屬舊世代 API,但理解其「欄位操作」、「add 自動進位」、「毫秒時間戳運算」等核心機制,對維護既有系統、處理相容性問題至關重要。掌握本文範例與表格,即可應付大多數日期時間操作需求。