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 阅读(872)
评论(1) 编辑 收藏