首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java Calendar 類完整指南:獲取時間字段、日期運算、月份陷阱與最佳實踐

     編輯:Java 綜合教學

Calendar 核心定位

  • 抽象類,提供「瞬間(毫秒值)」與「日曆字段」雙向轉換
  • getInstance() 返回具體子類實例(默認 GregorianCalendar)
  • 線程不安全,多線程環境勿共享實例

獲取實例與源碼機制

Calendar cal = Calendar.getInstance(); // 當前時區、Locale 的曆法

源碼會根據 Locale 返回不同曆法:

  • 泰語環境 → BuddhistCalendar
  • 日語環境 → JapaneseImperialCalendar
  • 默認 → GregorianCalendar(公曆)

常用字段常量

基礎用法示例

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);
int min   = cal.get(Calendar.MINUTE);
int sec   = cal.get(Calendar.SECOND);
int week  = cal.get(Calendar.DAY_OF_WEEK);

System.out.printf("現在是 %d年%d月%d日 %02d:%02d:%02d 星期%d%n",
    year, month, day, hour, min, sec, week);

日期運算:add / roll / set

// 一年後的今天
cal.add(Calendar.YEAR, 1);
// 下個月同一天(自動處理月末)
cal.add(Calendar.MONTH, 1);
// 加 10 天
cal.add(Calendar.DATE, 10);

// roll:不進位大字段
cal.roll(Calendar.MONTH, 1); // 12月 roll +1 → 1月,年份不變

// 直接設置
cal.set(2024, 11, 25); // 2024-12-25(月份 0 基)
cal.set(Calendar.YEAR, 2025);

實用技巧:獲取任意月份最後一天

public int getLastDayOfMonth(int year, int month) { // month 1-12
    Calendar cal = Calendar.getInstance();
    cal.set(year, month, 1);      // 設置為目標月第一天(month 為 0 基,傳入 6 實為 7 月)
    cal.add(Calendar.DATE, -1);   // 退一天 → 上月最後一天
    return cal.get(Calendar.DAY_OF_MONTH);
}
// 測試:getLastDayOfMonth(2024, 6) → 30(6月30日)

月份 0 基陷阱總結

常量含義取值範圍
YEAR年如 2024
MONTH月0-11(0=1月)⚠️
DAY_OF_MONTH日1-31
HOUR時(12制)0-11
HOUR_OF_DAY時(24制)0-23
MINUTE分0-59
SECOND秒0-59
DAY_OF_WEEK星期1=周日 ... 7=周六
操作正確寫法錯誤寫法
獲取月份cal.get(MONTH) + 1cal.get(MONTH)
設置月份cal.set(MONTH, 5) 表示 6 月cal.set(MONTH, 6) 實為 7 月
構造/設置完整日期cal.set(2024, 11, 25)cal.set(2024, 12, 25)

現代替代方案:java.time (Java 8+)

// 推薦:不可變、線程安全、API 清晰
LocalDate date = LocalDate.now();
LocalDateTime dt = LocalDateTime.now();
YearMonth ym = YearMonth.of(2024, 6);
int lastDay = ym.lengthOfMonth(); // 30

// 格式化
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dt.format(fmt));

避坑清單

  • ❌ 多線程共享 Calendar 實例
  • ❌ 忘記 MONTH + 1 顯示
  • ❌ 用 HOUR 而非 HOUR_OF_DAY 導致上午/下午混淆
  • ❌ roll 與 add 語義混淆
  • ✅ 新項目優先使用 java.time 包

Calendar 是 Java 早期日期時間 API,理解其 0 基月份、可變性與線程不安全特點,對維護舊代碼至關重要;新代碼請毫不猶豫選擇 java.time。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved