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