1 package test; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.Calendar; 6 import java.util.Date; 7 import java.util.TimeZone; 8 9 public class test { 10 private int year; 11 private int month; 12 private int day; 13 private boolean leap; 14 final static String chineseNumber[] = { "一", "二", "三", "四", "五", "六", "七", 15 "八", "九", "十", "十一", "十二" }; 16 static SimpleDateFormat chineseDateFormat = new SimpleDateFormat( 17 "yyyy年MM月dd日"); 18 final static long[] lunarInfo = new long[] { 0x04bd8, 0x04ae0, 0x0a570, 19 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 20 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 21 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 22 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 23 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 24 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 25 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 26 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 27 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 28 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 29 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 30 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 31 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 32 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 33 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 34 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 35 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 36 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 37 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 38 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 39 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 }; 40 41 // ====== 傳回農歷 y年的總天數 42 final private static int yearDays(int y) { 43 int i, sum = 348; 44 for (i = 0x8000; i > 0x8; i >>= 1) { 45 if ((lunarInfo[y - 1900] & i) != 0) 46 sum += 1; 47 } 48 return (sum + leapDays(y)); 49 } 50 51 // ====== 傳回農歷 y年閏月的天數 52 final private static int leapDays(int y) { 53 if (leapMonth(y) != 0) { 54 if ((lunarInfo[y - 1900] & 0x10000) != 0) 55 return 30; 56 else 57 return 29; 58 } else 59 return 0; 60 } 61 62 // ====== 傳回農歷 y年閏哪個月 1-12 , 沒閏傳回 0 63 final private static int leapMonth(int y) { 64 return (int) (lunarInfo[y - 1900] & 0xf); 65 } 66 67 // ====== 傳回農歷 y年m月的總天數 68 final private static int monthDays(int y, int m) { 69 if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) 70 return 29; 71 else 72 return 30; 73 } 74 75 // ====== 傳回農歷 y年的生肖 76 final public String animalsYear() { 77 final String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龍", "蛇", 78 "馬", "羊", "猴", "雞", "狗", "豬" }; 79 return Animals[(year - 4) % 12]; 80 } 81 82 // ====== 傳入 月日的offset 傳回干支, 0=甲子 83 final private static String cyclicalm(int num) { 84 final String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊", "己", "庚", 85 "辛", "壬", "癸" }; 86 final String[] Zhi = new String[] { "子", "丑", "寅", "卯", "辰", "巳", "午", 87 "未", "申", "酉", "戌", "亥" }; 88 return (Gan[num % 10] + Zhi[num % 12]); 89 } 90 91 // ====== 傳入 offset 傳回干支, 0=甲子 92 final public String cyclical() { 93 int num = year - 1900 + 36; 94 return (cyclicalm(num)); 95 } 96 97 /** 98 * 傳出y年m月d日對應的農歷. yearCyl3:農歷年與1864的相差數 ? monCyl4:從1900年1月31日以來,閏月數 99 * dayCyl5:與1900年1月31日相差的天數,再加40 ? 100 * 101 * @param cal 102 * @return 103 */ 104 public test(Calendar cal) { 105 int yearCyl, monCyl, dayCyl; 106 int leapMonth = 0; 107 Date baseDate = null; 108 try { 109 baseDate = chineseDateFormat.parse("1900年1月31日"); 110 } catch (ParseException e) { 111 e.printStackTrace(); // To change body of catch statement use 112 // Options | File Templates. 113 } 114 115 // 求出和1900年1月31日相差的天數 116 int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L); 117 dayCyl = offset + 40; 118 monCyl = 14; 119 120 // 用offset減去每農歷年的天數 121 // 計算當天是農歷第幾天 122 // i最終結果是農歷的年份 123 // offset是當年的第幾天 124 int iYear, daysOfYear = 0; 125 for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) { 126 daysOfYear = yearDays(iYear); 127 offset -= daysOfYear; 128 monCyl += 12; 129 } 130 if (offset < 0) { 131 offset += daysOfYear; 132 iYear--; 133 monCyl -= 12; 134 } 135 // 農歷年份 136 year = iYear; 137 138 yearCyl = iYear - 1864; 139 leapMonth = leapMonth(iYear); // 閏哪個月,1-12 140 leap = false; 141 142 // 用當年的天數offset,逐個減去每月(農歷)的天數,求出當天是本月的第幾天 143 int iMonth, daysOfMonth = 0; 144 for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) { 145 // 閏月 146 if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) { 147 --iMonth; 148 leap = true; 149 daysOfMonth = leapDays(year); 150 } else 151 daysOfMonth = monthDays(year, iMonth); 152 153 offset -= daysOfMonth; 154 // 解除閏月 155 if (leap && iMonth == (leapMonth + 1)) 156 leap = false; 157 if (!leap) 158 monCyl++; 159 } 160 // offset為0時,並且剛才計算的月份是閏月,要校正 161 if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) { 162 if (leap) { 163 leap = false; 164 } else { 165 leap = true; 166 --iMonth; 167 --monCyl; 168 } 169 } 170 // offset小於0時,也要校正 171 if (offset < 0) { 172 offset += daysOfMonth; 173 --iMonth; 174 --monCyl; 175 } 176 month = iMonth; 177 day = offset + 1; 178 } 179 180 public static String getChinaDayString(int day) { 181 String chineseTen[] = { "初", "十", "廿", "卅" }; 182 int n = day % 10 == 0 ? 9 : day % 10 - 1; 183 if (day > 30) 184 return ""; 185 if (day == 10) 186 return "初十"; 187 else 188 return chineseTen[day / 10] + chineseNumber[n]; 189 } 190 191 public String toString() { 192 return year + "年" + (leap ? "閏" : "") + chineseNumber[month - 1] + "月" 193 + getChinaDayString(day); 194 } 195 196 public static void main(String[] args) throws ParseException {
//獲取系統日期的農歷 197 // Calendar cal=Calendar.getInstance(); 198 // SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日"); 199 // cal.setTimeZone(TimeZone.getDefault()); 200 // System.out.println("公歷日期:"+sdf.format(cal.getTime())); 201 // test lunar=new test(cal); 202 // System.out.print("農歷日期:"); 203 // System.out.print(lunar.year+"年 "); 204 // System.out.print(lunar.month+"月 "); 205 // System.out.print(getChinaDayString(lunar.day)); 206 // System.out.println("*************"); 207 // System.out.println(lunar); 208 //獲取指定日期的農歷 209 Calendar today = Calendar.getInstance(); 210 today.setTime(chineseDateFormat.parse("1988年2月16日")); 211 test lunar = new test(today); 212 System.out.println("北京時間:" + chineseDateFormat.format(today.getTime()) 213 + " 農歷" + lunar); 214 } 215 216 }