|
???? 前幾天在blog中,對網友的java 萬年歷作修改,看到有的網友說能不能加上農歷,后來在網上看到有人寫過幾個陽歷轉陰歷的算法,我比較了一個發現,這個算法還算不錯,只要有的計算機編程基礎的人看明白應該是沒有問題的,其實這個就和我們以前在c中,判斷一天是周幾的算法差不多,都是和某一個特定的時間作比較,算出差多少天,再根據月大月小瑞月這些規則,算出是農歷的那年那月那日. package?clock;

import?java.text.ParseException;
import?java.text.SimpleDateFormat;
import?java.util.Calendar;
import?java.util.Date;

 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);
????}
}?
 ????? 在以前程序的label[i].setText(count +"");下設置label的浮動提示  ????????????try? {
????????????????now.setTime(chineseDateFormat.parse(year_log+"年"+(month_log+1)+"月"+count+"日"));
 ????????????}?catch?(ParseException?e)? {
????????????????e.printStackTrace();
????????????}
????????????label[i].setToolTipText("農歷"+new?Lunar(now));就能出現這種效果:
|