| 類 | 核心作用 | 關鍵方法/字段 |
|---|---|---|
Calendar | 抽象基類,定義日期字段常量 | YEAR、MONTH(0-11)、DATE、DAY_OF_WEEK、get/set/add/roll |
GregorianCalendar | 公曆(陽曆)具體實現 | 構造器多載、繼承 Calendar 所有方法 |
Java 標準庫**無內建農曆支援**,需自行實現:
核心數據:1901-2100 年每月大小月分佈、閏月規則、節氣(節/中氣)換算表。
算法思路:以已知基準日 (1901-01-01 = 農曆 1900 年 11 月 11 日) 為起點,計算目標日期與基準日的天數差,疊加推算農曆年月日。
public final class ChineseCalendar extends GregorianCalendar {
// 擴展字段常量
public static final int CHINESE_YEAR = 801;
public static final int CHINESE_MONTH = 802; // 正數=常月,負數=閏月
public static final int CHINESE_DATE = 803;
public static final int CHINESE_ZODIAC = 808; // 生肖
// ... 節氣、天干地支等常量
// 核心:公曆 → 農曆
private void computeChineseFields() {
// 1. 計算與基準日天數差
// 2. 疊加到基準農曆日期
// 3. 逐月扣減天數確定農曆年月
}
// 核心:農曆 → 公曆
private void computeGregorianFields() {
// 反向推算,含閏月處理邏輯
}
// 節氣計算:基於查表法 + 年份修正
public static int sectionalTerm(int year, int month) { /* ... */ }
public static int principleTerm(int year, int month) { /* ... */ }
// 重寫 get/set/add/roll 支援農曆字段
@Override public int get(int field) { /* ... */ }
@Override public void set(int field, int value) { /* ... */ }
@Override public void add(int field, int amount) { /* ... */ }
// 中文顯示支援
public String getChinese(int field) { /* 返回「甲子年」、「正月」、「初一」等 */ }
}
areChineseFieldsComputed、lastSetChinese 標記,確保公曆/農曆字段互相切換時自動重算。Calendar 整數字段機制,無缝整合 get/set/add/roll。chineseMonths[]、節氣用 sectionalTermMap[][] 緊湊存儲。ChineseCalendar cc = new ChineseCalendar(); // 當前時間
System.out.println(cc.getChineseDateString()); // 如:癸卯年正月初一
System.out.println(cc.getChinese(CHINESE_ZODIAC)); // 兔
System.out.println(cc.getChinese(CHINESE_TERM_OR_DATE)); // 智能顯示:節氣優先 > 初一顯示月 > 否則顯示日
// 設置農曆日期
cc.set(CHINESE_YEAR, 2024);
cc.set(CHINESE_MONTH, 1); // 正月
cc.set(CHINESE_DATE, 15); // 十五
System.out.println(cc.getSimpleGregorianDateString()); // 對應公曆日期
農曆算法屬於「領域知識密集型」代碼,建議直接引用成熟庫 (如 Hutool ChineseCalendar、LunarCalendar) 而非自行複製。若需自研,核心在於**基準日選擇**、**閏月判定規則**、以及**雙向同步狀態機**的正確性。