1 /* 2 * 创建时间 2004-12-920:32:56 3 */ 4 package lunarCalendar; 5 6 /** 7 * @author gcc 8 * 9 * TODO 10 */ 11 12 import java.text.ParseException; 13 import java.text.SimpleDateFormat; 14 import java.util.Calendar; 15 import java.util.Date; 16 17 public class LunarCalendar { 18 private int lyear; 19 20 private int lmonth; 21 22 private int lday; 23 24 private boolean leap; 25 26 private String solarTerms = ""; 27 28 private int yearCyl, monCyl, dayCyl; 29 30 private String solarFestival = ""; 31 32 private String lunarFestival = ""; 33 34 private Calendar baseDate = Calendar.getInstance(); 35 36 private Calendar offDate = Calendar.getInstance(); 37 38 private SimpleDateFormat chineseDateFormat = new SimpleDateFormat( 39 "yyyy年MM月dd日"); 40 41 final static long[] lunarInfo = new long[] { 0x04bd8, 0x04ae0, 0x0a570, 42 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 43 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 44 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 45 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 46 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 47 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 48 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 49 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 50 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 51 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 52 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 53 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 54 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 55 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 56 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 57 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 58 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 59 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 60 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 61 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 62 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 }; 63 64 final static String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊", "己", 65 "庚", "辛", "壬", "癸" }; 66 67 final static String[] Zhi = new String[] { "子", "丑", "寅", "卯", "辰", "巳", 68 "午", "未", "申", "酉", "戌", "亥" }; 69 70 final static String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龙", 71 "蛇", "马", "羊", "猴", "鸡", "狗", "猪" }; 72 73 final static String[] SolarTerm = new String[] { "小寒", "大寒", "立春", "雨水", 74 "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", 75 "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" }; 76 77 final static long[] STermInfo = new long[] { 0, 21208, 42467, 63836, 85337, 78 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 79 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 80 462224, 483532, 504758 }; 81 82 final static String chineseMonthNumber[] = { "正", "二", "三", "四", "五", "六", 83 "七", "八", "九", "十", "冬", "腊" }; 84 85 final static String[] sFtv = new String[] { "0101*元旦", "0214 情人节", 86 "0308 妇女节", "0312 植树节", "0314 国际警察日", "0315 消费者权益日", "0323 世界气象日", 87 "0401 愚人节", "0407 世界卫生日", "0501*劳动节", "0504 青年节", "0508 红十字日", 88 "0512 护士节", "0515 国际家庭日", "0517 世界电信日", "0519 全国助残日", "0531 世界无烟日", 89 "0601 儿童节", "0605 世界环境日", "0606 全国爱眼日", "0623 奥林匹克日", "0625 全国土地日", 90 "0626 反毒品日", "0701 建党节", "0707 抗战纪念日", "0711 世界人口日", "0801 建军节", 91 "0908 国际扫盲日", "0909 毛xx逝世纪念", "0910 教师节", "0917 国际和平日", 92 "0920 国际爱牙日", "0922 国际聋人节", "0927 世界旅游日", "0928 孔子诞辰", "1001*国庆节", 93 "1004 世界动物日", "1006 老人节", "1007 国际住房日", "1009 世界邮政日", "1015 国际盲人节", 94 "1016 世界粮食日", "1024 联合国日", "1031 万圣节", "1108 中国记者日", "1109 消防宣传日", 95 "1112 孙中山诞辰", "1114 世界糖尿病日", "1117 国际大学生节", "1128 感恩节", 96 "1201 世界艾滋病日", "1203 世界残疾人日", "1209 世界足球日", "1220 澳门回归", 97 "1225 圣诞节", "1226 毛xx诞辰" }; 98 99 final static String[] lFtv = { "0101*春节", "0115 元宵", "0505 端午", 100 "0707 七夕", "0815 中秋", "0909 重阳", "1208 腊八", "1223 小年", 101 "0100*除夕" }; 102 103 final static String[] wFtv = { "0521 母亲节", "0631 父亲节" };//每年6月第3个星期日是父亲节,5月的第2个星期日是母亲节 104 105 //星期日是一个周的第1天第3个星期日也就是第3个完整周的第一天 106 107 // 108 private LunarCalendar() { 109 baseDate.setMinimalDaysInFirstWeek(7);//设置一个月的第一个周是一个完整周 110 111 } 112 113 final private static int lYearDays(int y)//====== 传回农历 y年的总天数 114 { 115 int i, sum = 348; 116 for (i = 0x8000; i > 0x8; i >>= 1) { 117 if ((lunarInfo[y - 1900] & i) != 0) 118 sum += 1; 119 } 120 return (sum + leapDays(y)); 121 } 122 123 final private static int leapDays(int y)//====== 传回农历 y年闰月的天数 124 { 125 if (leapMonth(y) != 0) { 126 if ((lunarInfo[y - 1900] & 0x10000) != 0) 127 return 30; 128 else 129 return 29; 130 } else 131 return 0; 132 } 133 134 final private static int leapMonth(int y)//====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0 135 { 136 return (int) (lunarInfo[y - 1900] & 0xf); 137 } 138 139 final public static int monthDays(int y, int m)//====== 传回农历 y年m月的总天数 140 { 141 if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) 142 return 29; 143 else 144 return 30; 145 } 146 147 final private static String AnimalsYear(int y)//====== 传回农历 y年的生肖 148 { 149 150 return Animals[(y - 4) % 12]; 151 } 152 153 final private static String cyclical(int num)//====== 传入 的offset 传回干支, 154 // 0=甲子 155 { 156 157 return (Gan[num % 10] + Zhi[num % 12]); 158 } 159 160 // ===== 某年的第n个节气为几日(从0小寒起算) 161 final private int sTerm(int y, int n) { 162 163 offDate.set(1900, 0, 6, 2, 5, 0); 164 long temp = offDate.getTime().getTime(); 165 offDate 166 .setTime(new Date( 167 (long) ((31556925974.7 * (y - 1900) + STermInfo[n] * 60000L) + temp))); 168 169 return offDate.get(Calendar.DAY_OF_MONTH); 170 } 171 172 /** 173 * 传出y年m月d日对应的农历. 174 * 175 */ 176 private void CalculateLunarCalendar(int y, int m, int d) { 177 178 int leapMonth = 0; 179 180 try { 181 baseDate.setTime(chineseDateFormat.parse("1900年1月31日")); 182 183 } catch (ParseException e) { 184 e.printStackTrace(); 185 } 186 long base = baseDate.getTimeInMillis(); 187 try { 188 baseDate.setTime(chineseDateFormat.parse(y + "年" + m + "月" + d 189 + "日")); 190 191 } catch (ParseException e) { 192 e.printStackTrace(); 193 } 194 long obj = baseDate.getTimeInMillis(); 195 196 197 int offset = (int) ((obj - base) / 86400000L); 198 //System.out.println(offset); 199 //求出和1900年1月31日相差的天数 200 201 dayCyl = offset + 40;//干支天 202 monCyl = 14;//干支月 203 204 //用offset减去每农历年的天数 205 // 计算当天是农历第几天 206 //i最终结果是农历的年份 207 //offset是当年的第几天 208 int iYear, daysOfYear = 0; 209 for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) { 210 daysOfYear = lYearDays(iYear); 211 offset -= daysOfYear; 212 monCyl += 12; 213 } 214 if (offset < 0) { 215 offset += daysOfYear; 216 iYear--; 217 monCyl -= 12; 218 } 219 //农历年份 220 lyear = iYear; 221 222 yearCyl = iYear - 1864;//***********干支年**********// 223 224 leapMonth = leapMonth(iYear); //闰哪个月,1-12 225 leap = false; 226 227 //用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天 228 int iMonth, daysOfMonth = 0; 229 for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) { 230 //闰月 231 if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) { 232 --iMonth; 233 leap = true; 234 daysOfMonth = leapDays(iYear); 235 } else 236 daysOfMonth = monthDays(iYear, iMonth); 237 238 offset -= daysOfMonth; 239 //解除闰月 240 if (leap && iMonth == (leapMonth + 1)) 241 leap = false; 242 if (!leap) 243 monCyl++; 244 } 245 //offset为0时,并且刚才计算的月份是闰月,要校正 246 if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) { 247 if (leap) { 248 leap = false; 249 } else { 250 leap = true; 251 --iMonth; 252 --monCyl; 253 } 254 } 255 //offset小于0时,也要校正 256 if (offset < 0) { 257 offset += daysOfMonth; 258 --iMonth; 259 --monCyl; 260 } 261 lmonth = iMonth; 262 lday = offset + 1; 263 264 //******************计算节气**********// 265 266 if (d == sTerm(y, (m - 1) * 2)) 267 solarTerms = SolarTerm[(m - 1) * 2]; 268 else if (d == sTerm(y, (m - 1) * 2 + 1)) 269 solarTerms = SolarTerm[(m - 1) * 2 + 1]; 270 else 271 solarTerms = ""; 272 273 //计算公历节日 274 this.solarFestival = ""; 275 for (int i = 0; i < sFtv.length; i++) { 276 if (Integer.parseInt(sFtv[i].substring(0, 2)) == m 277 && Integer.parseInt(sFtv[i].substring(2, 4)) == d) { 278 solarFestival = sFtv[i].substring(5); 279 } 280 } 281 //计算农历节日 282 this.lunarFestival = ""; 283 for (int i = 0; i < lFtv.length; i++) { 284 if (Integer.parseInt(lFtv[i].substring(0, 2)) == lmonth 285 && Integer.parseInt(lFtv[i].substring(2, 4)) == lday) { 286 lunarFestival = lFtv[i].substring(5); 287 } 288 } 289 //计算月周节日 290 291 // System.out.println(baseDate.get(Calendar.WEEK_OF_MONTH) + "" 292 // + baseDate.get(Calendar.DAY_OF_WEEK)); 293 294 for (int i = 0; i < wFtv.length; i++) { 295 if (Integer.parseInt(wFtv[i].substring(0, 2)) == m 296 && Integer.parseInt(wFtv[i].substring(2, 3)) == baseDate 297 .get(Calendar.WEEK_OF_MONTH) 298 && Integer.parseInt(wFtv[i].substring(3, 4)) == baseDate 299 .get(Calendar.DAY_OF_WEEK)) { 300 solarFestival += wFtv[i].substring(5); 301 } 302 } 303 304 } 305 306 //set方法 307 public void set(int y, int m, int d) { 308 309 CalculateLunarCalendar(y, m, d); 310 } 311 public void set(Calendar cal) { 312 313 CalculateLunarCalendar(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1,cal.get(Calendar.DAY_OF_MONTH)); 314 } 315 // //get方法组 316 public static LunarCalendar getInstance() { 317 318 return new LunarCalendar(); 319 }
320}
原文:http://www.cnblogs.com/gccBlog/p/3549624.html