在 Java 開發中,處理日期與時間是常見需求。標準庫提供的 Calendar 與 Date 雖然功能強大,但在處理農曆、節氣、節日等中國特有的曆法資訊時顯得力不從心。本文將介紹一個自定義的 ChineseCalendar 萬年曆類,以及一組實用的 Calendar 封裝工具方法,幫助開發者輕鬆應對複雜的時間計算場景。
ChineseCalendar 繼承自 GregorianCalendar,支援 1901 年至 2100 年之間的農曆轉換、節氣計算、天干地支、生肖以及中英文日期顯示。其核心特點如下:
CHINESE_YEAR、CHINESE_MONTH、CHINESE_DATE 等欄位,可直接透過 get() 方法獲取。CHINESE_SECTIONAL_TERM(節氣)、CHINESE_PRINCIPLE_TERM(中氣)、LUNAR_FESTIVAL(農曆節日)、SOLAR_FESTIVAL(陽曆節日)等常量。set()、add()、roll() 方法設定,其他屬性自動計算。getChinese(int field) 方法可直接取得農曆屬性的中文文字(如「甲子年」、「正月初一」)。public final class ChineseCalendar extends GregorianCalendar {
// 農曆欄位常量(從 801 起始,避免與父類衝突)
public static final int CHINESE_YEAR = 801;
public static final int CHINESE_MONTH = 802; // 1 起始,負數表示閏月
public static final int CHINESE_DATE = 803;
public static final int CHINESE_SECTIONAL_TERM = 804;
public static final int CHINESE_PRINCIPLE_TERM = 805;
public static final int CHINESE_HEAVENLY_STEM = 806;
public static final int CHINESE_EARTHLY_BRANCH = 807;
public static final int CHINESE_ZODIAC = 808;
public static final int CHINESE_TERM_OR_DATE = 888; // 模仿台曆顯示邏輯
// ... 節日相關常量
}
注意事項:
Calendar 慣例(0-11),農曆月份則從 1 起始,閏月以負數表示。clear() 方法,可能導致農曆與公曆日期對應關係錯亂。getSimpleDateString() 回傳公曆日期字串(月份已修正),getSimpleChineseDateString() 回傳農曆日期字串(閏月以 * 標示)。在開發日曆元件或排程系統時,經常需要「取得本月天數」、「計算上個月最後一天是星期幾」等操作。CalendarSelfDefineTest 將這些高頻邏輯封裝為靜態工具方法,直接操作 java.util.Calendar 實例,簡潔高效。
| 方法 | 功能說明 | 回傳值範例 |
|---|---|---|
getYear(cal) | 取得年份 | 2013 |
getMonth(cal) | 取得月份(0-11) | 8 代表 9 月 |
getLastMonth(cal) | 取得上個月份 | 11 代表 12 月 |
getNextMonth(cal) | 取得下個月份 | 1 代表 2 月 |
getDay(cal) | 取得日期 | 18 |
getWeekDay(cal) | 取得星期幾(1=星期日) | 4 代表星期三 |
getMonthDays(cal) | 取得當月總天數 | 30 |
getPrevMonthDays(cal) | 取得上月總天數 | 31 |
getNextMonthDays(cal) | 取得下月總天數 | 31 |
getFirstDayWeekday(cal) | 取得本月 1 號星期幾 | 3 代表星期二 |
getLastDayWeekday(cal) | 取得本月最後一天星期幾 | 6 代表星期五 |
getLastDayWeekdayOfPrevMonth(cal) | 取得上月最後一天星期幾 | 1 代表星期日 |
getFirstDayWeekdayOfNextMonth(cal) | 取得下月 1 號星期幾 | 5 代表星期四 |
所有跨月計算方法均採用 Calendar tmpCal = (Calendar) cal.clone(); 模式,確保原始 Calendar 物件不被修改,符合函數式編程的無副作用原則。
public static int getPrevMonthDays(Calendar cal) {
Calendar tmpCal = (Calendar) cal.clone();
tmpCal.add(Calendar.MONTH, -1);
return tmpCal.getActualMaximum(Calendar.DATE);
}
ChineseCalendar 的節氣/節日資料與工具類的週曆計算,快速構建含農曆的日期選擇器。getFirstDayWeekday()、getMonthDays() 進行月視圖佈局。getPrevMonthDays()、getNextMonthDays() 快速切換統計區間。ChineseCalendar 解決了 Java 標準庫缺乏農曆支援的痛點,而 CalendarSelfDefineTest 則將繁瑣的 Calendar API 封裝為語意清晰的工具方法。兩者結合,能大幅提升涉及複雜時間邏輯業務的開發效率與程式碼可維護性。