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

Java 實現多功能萬年曆:GregorianCalendar 與農曆算法完整源碼解析

     編輯:Java 相關知識

核心類體系回顧

類核心作用關鍵方法/字段
Calendar抽象基類,定義日期字段常量YEAR、MONTH(0-11)、DATE、DAY_OF_WEEK、get/set/add/roll
GregorianCalendar公曆(陽曆)具體實現構造器多載、繼承 Calendar 所有方法

萬年曆核心難點:農曆(陰曆)計算

Java 標準庫**無內建農曆支援**,需自行實現:
核心數據:1901-2100 年每月大小月分佈、閏月規則、節氣(節/中氣)換算表。
算法思路:以已知基準日 (1901-01-01 = 農曆 1900 年 11 月 11 日) 為起點,計算目標日期與基準日的天數差,疊加推算農曆年月日。

ChineseCalendar 完整實現精華 (節選關鍵邏輯)

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[][] 緊湊存儲。
  • 邊界保護:限制 1901-2100 年範圍,超出自動鉗制。

使用示例

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) 而非自行複製。若需自研,核心在於**基準日選擇**、**閏月判定規則**、以及**雙向同步狀態機**的正確性。

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