1
2
3
4 package lunarCalendar;
5
6
7
8
9
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 父亲节" };
104
105
106
107
108 private LunarCalendar() {
109 baseDate.setMinimalDaysInFirstWeek(7);
110
111 }
112
113 final private static int lYearDays(int 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)
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)
135 {
136 return (int) (lunarInfo[y - 1900] & 0xf);
137 }
138
139 final public static int monthDays(int y, int 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)
148 {
149
150 return Animals[(y - 4) % 12];
151 }
152
153 final private static String cyclical(int num)
154
155 {
156
157 return (Gan[num % 10] + Zhi[num % 12]);
158 }
159
160
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
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
199
200
201 dayCyl = offset + 40;
202 monCyl = 14;
203
204
205
206
207
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);
225 leap = false;
226
227
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
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
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
292
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
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
316 public static LunarCalendar getInstance() {
317
318 return new LunarCalendar();
319 }
320}