



public ? class ?Lunar? {
???? private ? int ?year;
???? private ? int ?month;
???? private ? int ?day;
???? private ? boolean ?leap;
???? final ? static ?String?chineseNumber[]? = ? { " 一 " ,? " 二 " ,? " 三 " ,? " 四 " ,? " 五 " ,? " 六 " ,? " 七 " ,? " 八 " ,? " 九 " ,? " 十 " ,? " 十一 " ,? " 十二 " } ;
???? static ?SimpleDateFormat?chineseDateFormat? = ? new ?SimpleDateFormat( " yyyy年MM月dd日 " );
???? final ? static ? long []?lunarInfo? = ? new ? long []
???? { 0x04bd8 ,? 0x04ae0 ,? 0x0a570 ,? 0x054d5 ,? 0x0d260 ,? 0x0d950 ,? 0x16554 ,? 0x056a0 ,? 0x09ad0 ,? 0x055d2 ,
????? 0x04ae0 ,? 0x0a5b6 ,? 0x0a4d0 ,? 0x0d250 ,? 0x1d255 ,? 0x0b540 ,? 0x0d6a0 ,? 0x0ada2 ,? 0x095b0 ,? 0x14977 ,
????? 0x04970 ,? 0x0a4b0 ,? 0x0b4b5 ,? 0x06a50 ,? 0x06d40 ,? 0x1ab54 ,? 0x02b60 ,? 0x09570 ,? 0x052f2 ,? 0x04970 ,
????? 0x06566 ,? 0x0d4a0 ,? 0x0ea50 ,? 0x06e95 ,? 0x05ad0 ,? 0x02b60 ,? 0x186e3 ,? 0x092e0 ,? 0x1c8d7 ,? 0x0c950 ,
????? 0x0d4a0 ,? 0x1d8a6 ,? 0x0b550 ,? 0x056a0 ,? 0x1a5b4 ,? 0x025d0 ,? 0x092d0 ,? 0x0d2b2 ,? 0x0a950 ,? 0x0b557 ,
????? 0x06ca0 ,? 0x0b550 ,? 0x15355 ,? 0x04da0 ,? 0x0a5d0 ,? 0x14573 ,? 0x052d0 ,? 0x0a9a8 ,? 0x0e950 ,? 0x06aa0 ,
????? 0x0aea6 ,? 0x0ab50 ,? 0x04b60 ,? 0x0aae4 ,? 0x0a570 ,? 0x05260 ,? 0x0f263 ,? 0x0d950 ,? 0x05b57 ,? 0x056a0 ,
????? 0x096d0 ,? 0x04dd5 ,? 0x04ad0 ,? 0x0a4d0 ,? 0x0d4d4 ,? 0x0d250 ,? 0x0d558 ,? 0x0b540 ,? 0x0b5a0 ,? 0x195a6 ,
????? 0x095b0 ,? 0x049b0 ,? 0x0a974 ,? 0x0a4b0 ,? 0x0b27a ,? 0x06a50 ,? 0x06d40 ,? 0x0af46 ,? 0x0ab60 ,? 0x09570 ,
????? 0x04af5 ,? 0x04970 ,? 0x064b0 ,? 0x074a3 ,? 0x0ea50 ,? 0x06b58 ,? 0x055c0 ,? 0x0ab60 ,? 0x096d5 ,? 0x092e0 ,
????? 0x0c960 ,? 0x0d954 ,? 0x0d4a0 ,? 0x0da50 ,? 0x07552 ,? 0x056a0 ,? 0x0abb7 ,? 0x025d0 ,? 0x092d0 ,? 0x0cab5 ,
????? 0x0a950 ,? 0x0b4a0 ,? 0x0baa4 ,? 0x0ad50 ,? 0x055d9 ,? 0x04ba0 ,? 0x0a5b0 ,? 0x15176 ,? 0x052b0 ,? 0x0a930 ,
????? 0x07954 ,? 0x06aa0 ,? 0x0ad50 ,? 0x05b52 ,? 0x04b60 ,? 0x0a6e6 ,? 0x0a4e0 ,? 0x0d260 ,? 0x0ea65 ,? 0x0d530 ,
????? 0x05aa0 ,? 0x076a3 ,? 0x096d0 ,? 0x04bd7 ,? 0x04ad0 ,? 0x0a4d0 ,? 0x1d0b6 ,? 0x0d250 ,? 0x0d520 ,? 0x0dd45 ,
????? 0x0b5a0 ,? 0x056d0 ,? 0x055b2 ,? 0x049b0 ,? 0x0a577 ,? 0x0a4b0 ,? 0x0aa50 ,? 0x1b255 ,? 0x06d20 ,? 0x0ada0 } ;
???? // ======?傳回農歷?y年的總天數
???? final ? private ? static ? int ?yearDays( int ?y)? {
???????? int ?i,?sum? = ? 348 ;
???????? for ?(i? = ? 0x8000 ;?i? > ? 0x8 ;?i? >>= ? 1 )? {
???????????? if ?((lunarInfo[y? - ? 1900 ]? & ?i)? != ? 0 )?sum? += ? 1 ;
????????}
???????? return ?(sum? + ?leapDays(y));
????}
???? // ======?傳回農歷?y年閏月的天數
???? final ? private ? static ? int ?leapDays( int ?y)? {
???????? if ?(leapMonth(y)? != ? 0 )? {
???????????? if ?((lunarInfo[y? - ? 1900 ]? & ? 0x10000 )? != ? 0 )
???????????????? return ? 30 ;
???????????? else
???????????????? return ? 29 ;
????????} ? else
???????????? return ? 0 ;
????}
???? // ======?傳回農歷?y年閏哪個月?1-12?,?沒閏傳回?0
???? final ? private ? static ? int ?leapMonth( int ?y)? {
???????? return ?( int )?(lunarInfo[y? - ? 1900 ]? & ? 0xf );
????}
???? // ======?傳回農歷?y年m月的總天數
???? final ? private ? static ? int ?monthDays( int ?y,? int ?m)? {
???????? if ?((lunarInfo[y? - ? 1900 ]? & ?( 0x10000 ? >> ?m))? == ? 0 )
???????????? return ? 29 ;
???????? else
???????????? return ? 30 ;
????}
???? // ======?傳回農歷?y年的生肖
???? final ? public ?String?animalsYear()? {
???????? final ?String[]?Animals? = ? new ?String[] { " 鼠 " ,? " 牛 " ,? " 虎 " ,? " 兔 " ,? " 龍 " ,? " 蛇 " ,? " 馬 " ,? " 羊 " ,? " 猴 " ,? " 雞 " ,? " 狗 " ,? " 豬 " } ;
???????? return ?Animals[(year? - ? 4 )? % ? 12 ];
????}
???? // ======?傳入?月日的offset?傳回干支,?0=甲子
???? final ? private ? static ?String?cyclicalm( int ?num)? {
???????? final ?String[]?Gan? = ? new ?String[] { " 甲 " ,? " 乙 " ,? " 丙 " ,? " 丁 " ,? " 戊 " ,? " 己 " ,? " 庚 " ,? " 辛 " ,? " 壬 " ,? " 癸 " } ;
???????? final ?String[]?Zhi? = ? new ?String[] { " 子 " ,? " 丑 " ,? " 寅 " ,? " 卯 " ,? " 辰 " ,? " 巳 " ,? " 午 " ,? " 未 " ,? " 申 " ,? " 酉 " ,? " 戌 " ,? " 亥 " } ;
???????? return ?(Gan[num? % ? 10 ]? + ?Zhi[num? % ? 12 ]);
????}
???? // ======?傳入?offset?傳回干支,?0=甲子
???? final ? public ?String?cyclical()? {
???????? int ?num? = ?year? - ? 1900 ? + ? 36 ;
???????? return ?(cyclicalm(num));
????}
???? /**?*/ /**
?????*?傳出y年m月d日對應的農歷.
?????*?yearCyl3:農歷年與1864的相差數???????????????
?????*?monCyl4:從1900年1月31日以來,閏月數
?????*?dayCyl5:與1900年1月31日相差的天數,再加40???????
?????*? @param ?cal?
?????*? @return ?
????? */
???? public ?Lunar(Calendar?cal)? {
????????@SuppressWarnings( " unused " )? int ?yearCyl,?monCyl,?dayCyl;
???????? int ?leapMonth? = ? 0 ;
????????Date?baseDate? = ? null ;
???????? try ? {
????????????baseDate? = ?chineseDateFormat.parse( " 1900年1月31日 " );
????????} ? catch ?(ParseException?e)? {
????????????e.printStackTrace();?? // To?change?body?of?catch?statement?use?Options?|?File?Templates.
????????}
???????? // 求出和1900年1月31日相差的天數
???????? int ?offset? = ?( int )?((cal.getTime().getTime()? - ?baseDate.getTime())? / ? 86400000L );
????????dayCyl? = ?offset? + ? 40 ;
????????monCyl? = ? 14 ;
???????? // 用offset減去每農歷年的天數
???????? // ?計算當天是農歷第幾天
???????? // i最終結果是農歷的年份
???????? // offset是當年的第幾天
???????? int ?iYear,?daysOfYear? = ? 0 ;
???????? for ?(iYear? = ? 1900 ;?iYear? < ? 2050 ? && ?offset? > ? 0 ;?iYear ++ )? {
????????????daysOfYear? = ?yearDays(iYear);
????????????offset? -= ?daysOfYear;
????????????monCyl? += ? 12 ;
????????}
???????? if ?(offset? < ? 0 )? {
????????????offset? += ?daysOfYear;
????????????iYear -- ;
????????????monCyl? -= ? 12 ;
????????}
???????? // 農歷年份
????????year? = ?iYear;
????????yearCyl? = ?iYear? - ? 1864 ;
????????leapMonth? = ?leapMonth(iYear);? // 閏哪個月,1-12
????????leap? = ? false ;
???????? // 用當年的天數offset,逐個減去每月(農歷)的天數,求出當天是本月的第幾天
???????? int ?iMonth,?daysOfMonth? = ? 0 ;
???????? for ?(iMonth? = ? 1 ;?iMonth? < ? 13 ? && ?offset? > ? 0 ;?iMonth ++ )? {
???????????? // 閏月
???????????? if ?(leapMonth? > ? 0 ? && ?iMonth? == ?(leapMonth? + ? 1 )? && ? ! leap)? {
???????????????? -- iMonth;
????????????????leap? = ? true ;
????????????????daysOfMonth? = ?leapDays(year);
????????????} ? else
????????????????daysOfMonth? = ?monthDays(year,?iMonth);
????????????offset? -= ?daysOfMonth;
???????????? // 解除閏月
???????????? if ?(leap? && ?iMonth? == ?(leapMonth? + ? 1 ))?leap? = ? false ;
???????????? if ?( ! leap)?monCyl ++ ;
????????}
???????? // offset為0時,并且剛才計算的月份是閏月,要校正
???????? if ?(offset? == ? 0 ? && ?leapMonth? > ? 0 ? && ?iMonth? == ?leapMonth? + ? 1 )? {
???????????? if ?(leap)? {
????????????????leap? = ? false ;
????????????} ? else ? {
????????????????leap? = ? true ;
???????????????? -- iMonth;
???????????????? -- monCyl;
????????????}
????????}
???????? // offset小于0時,也要校正
???????? if ?(offset? < ? 0 )? {
????????????offset? += ?daysOfMonth;
???????????? -- iMonth;
???????????? -- monCyl;
????????}
????????month? = ?iMonth;
????????day? = ?offset? + ? 1 ;
????}
???? public ? static ?String?getChinaDayString( int ?day)? {
????????String?chineseTen[]? = ? { " 初 " ,? " 十 " ,? " 廿 " ,? " 卅 " } ;
???????? int ?n? = ?day? % ? 10 ? == ? 0 ? ? ? 9 ?:?day? % ? 10 ? - ? 1 ;
???????? if ?(day? > ? 30 )
???????????? return ? "" ;
???????? if ?(day? == ? 10 )
???????????? return ? " 初十 " ;
???????? else
???????????? return ?chineseTen[day? / ? 10 ]? + ?chineseNumber[n];
????}
???? public ?String?toString()? {
???????? return ?year? + ? " 年 " ? + ?(leap? ? ? " 閏 " ?:? "" )? + ?chineseNumber[month? - ? 1 ]? + ? " 月 " ? + ?getChinaDayString(day);
????}
???? public ? static ? void ?main(String[]?args)? throws ?ParseException? {
????????Calendar?today? = ?Calendar.getInstance();
????????today.setTime(chineseDateFormat.parse( " 2003年1月1日 " ));
????????Lunar?lunar? = ? new ?Lunar(today);
????????System.out.println( " 北京時間: " ? + ?chineseDateFormat.format(today.getTime())? + ? " 農歷 " ? + ?lunar);
????}
} ?