import
java.text.ParseException;
import
java.text.SimpleDateFormat;
import
java.util.Calendar;
import
java.util.Date;
public
class
Lunar
{
private
int
year;
private
int
month;
private
int
day;
private
boolean
leap;
final
static
String chineseNumber[]
=
{
"
一
"
,
"
二
"
,
"
三
"
,
"
四
"
,
"
五
"
,
"
六
"
,
"
七
"
,
"
八
"
,
"
九
"
,
"
十
"
,
"
十一
"
,
"
十二
"
}
;
static
SimpleDateFormat chineseDateFormat
=
new
SimpleDateFormat(
"
yyyy年MM月dd日
"
);
final
static
long
[] lunarInfo
=
new
long
[]
{
0x04bd8
,
0x04ae0
,
0x0a570
,
0x054d5
,
0x0d260
,
0x0d950
,
0x16554
,
0x056a0
,
0x09ad0
,
0x055d2
,
0x04ae0
,
0x0a5b6
,
0x0a4d0
,
0x0d250
,
0x1d255
,
0x0b540
,
0x0d6a0
,
0x0ada2
,
0x095b0
,
0x14977
,
0x04970
,
0x0a4b0
,
0x0b4b5
,
0x06a50
,
0x06d40
,
0x1ab54
,
0x02b60
,
0x09570
,
0x052f2
,
0x04970
,
0x06566
,
0x0d4a0
,
0x0ea50
,
0x06e95
,
0x05ad0
,
0x02b60
,
0x186e3
,
0x092e0
,
0x1c8d7
,
0x0c950
,
0x0d4a0
,
0x1d8a6
,
0x0b550
,
0x056a0
,
0x1a5b4
,
0x025d0
,
0x092d0
,
0x0d2b2
,
0x0a950
,
0x0b557
,
0x06ca0
,
0x0b550
,
0x15355
,
0x04da0
,
0x0a5d0
,
0x14573
,
0x052d0
,
0x0a9a8
,
0x0e950
,
0x06aa0
,
0x0aea6
,
0x0ab50
,
0x04b60
,
0x0aae4
,
0x0a570
,
0x05260
,
0x0f263
,
0x0d950
,
0x05b57
,
0x056a0
,
0x096d0
,
0x04dd5
,
0x04ad0
,
0x0a4d0
,
0x0d4d4
,
0x0d250
,
0x0d558
,
0x0b540
,
0x0b5a0
,
0x195a6
,
0x095b0
,
0x049b0
,
0x0a974
,
0x0a4b0
,
0x0b27a
,
0x06a50
,
0x06d40
,
0x0af46
,
0x0ab60
,
0x09570
,
0x04af5
,
0x04970
,
0x064b0
,
0x074a3
,
0x0ea50
,
0x06b58
,
0x055c0
,
0x0ab60
,
0x096d5
,
0x092e0
,
0x0c960
,
0x0d954
,
0x0d4a0
,
0x0da50
,
0x07552
,
0x056a0
,
0x0abb7
,
0x025d0
,
0x092d0
,
0x0cab5
,
0x0a950
,
0x0b4a0
,
0x0baa4
,
0x0ad50
,
0x055d9
,
0x04ba0
,
0x0a5b0
,
0x15176
,
0x052b0
,
0x0a930
,
0x07954
,
0x06aa0
,
0x0ad50
,
0x05b52
,
0x04b60
,
0x0a6e6
,
0x0a4e0
,
0x0d260
,
0x0ea65
,
0x0d530
,
0x05aa0
,
0x076a3
,
0x096d0
,
0x04bd7
,
0x04ad0
,
0x0a4d0
,
0x1d0b6
,
0x0d250
,
0x0d520
,
0x0dd45
,
0x0b5a0
,
0x056d0
,
0x055b2
,
0x049b0
,
0x0a577
,
0x0a4b0
,
0x0aa50
,
0x1b255
,
0x06d20
,
0x0ada0
}
;
//
====== 传回农历 y年的总天数
final
private
static
int
yearDays(
int
y)
{
int
i, sum
=
348
;
for
(i
=
0x8000
; i
>
0x8
; i
>>=
1
)
{
if
((lunarInfo[y
-
1900
]
&
i)
!=
0
) sum
+=
1
;
}
return
(sum
+
leapDays(y));
}
//
====== 传回农历 y年闰月的天数
final
private
static
int
leapDays(
int
y)
{
if
(leapMonth(y)
!=
0
)
{
if
((lunarInfo[y
-
1900
]
&
0x10000
)
!=
0
)
return
30
;
else
return
29
;
}
else
return
0
;
}
//
====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
final
private
static
int
leapMonth(
int
y)
{
return
(
int
) (lunarInfo[y
-
1900
]
&
0xf
);
}
//
====== 传回农历 y年m月的总天数
final
private
static
int
monthDays(
int
y,
int
m)
{
if
((lunarInfo[y
-
1900
]
&
(
0x10000
>>
m))
==
0
)
return
29
;
else
return
30
;
}
//
====== 传回农历 y年的生肖
final
public
String animalsYear()
{
final
String[] Animals
=
new
String[]
{
"
鼠
"
,
"
牛
"
,
"
虎
"
,
"
兔
"
,
"
龙
"
,
"
蛇
"
,
"
马
"
,
"
羊
"
,
"
猴
"
,
"
鸡
"
,
"
狗
"
,
"
猪
"
}
;
return
Animals[(year
-
4
)
%
12
];
}
//
====== 传入 月日的offset 传回干支, 0=甲子
final
private
static
String cyclicalm(
int
num)
{
final
String[] Gan
=
new
String[]
{
"
甲
"
,
"
乙
"
,
"
丙
"
,
"
丁
"
,
"
戊
"
,
"
己
"
,
"
庚
"
,
"
辛
"
,
"
壬
"
,
"
癸
"
}
;
final
String[] Zhi
=
new
String[]
{
"
子
"
,
"
丑
"
,
"
寅
"
,
"
卯
"
,
"
辰
"
,
"
巳
"
,
"
午
"
,
"
未
"
,
"
申
"
,
"
酉
"
,
"
戌
"
,
"
亥
"
}
;
return
(Gan[num
%
10
]
+
Zhi[num
%
12
]);
}
//
====== 传入 offset 传回干支, 0=甲子
final
public
String cyclical()
{
int
num
=
year
-
1900
+
36
;
return
(cyclicalm(num));
}
/** */
/**
* 传出y年m月d日对应的农历.
* yearCyl3:农历年与1864的相差数 ?
* monCyl4:从1900年1月31日以来,闰月数
* dayCyl5:与1900年1月31日相差的天数,再加40 ?
*
@param
cal
*
@return
*/
public
Lunar(Calendar cal)
{
@SuppressWarnings(
"
unused
"
)
int
yearCyl, monCyl, dayCyl;
int
leapMonth
=
0
;
Date baseDate
=
null
;
try
{
baseDate
=
chineseDateFormat.parse(
"
1900年1月31日
"
);
}
catch
(ParseException e)
{
e.printStackTrace();
//
To change body of catch statement use Options | File Templates.
}
//
求出和1900年1月31日相差的天数
int
offset
=
(
int
) ((cal.getTime().getTime()
-
baseDate.getTime())
/
86400000L
);
dayCyl
=
offset
+
40
;
monCyl
=
14
;
//
用offset减去每农历年的天数
//
计算当天是农历第几天
//
i最终结果是农历的年份
//
offset是当年的第几天
int
iYear, daysOfYear
=
0
;
for
(iYear
=
1900
; iYear
<
2050
&&
offset
>
0
; iYear
++
)
{
daysOfYear
=
yearDays(iYear);
offset
-=
daysOfYear;
monCyl
+=
12
;
}
if
(offset
<
0
)
{
offset
+=
daysOfYear;
iYear
--
;
monCyl
-=
12
;
}
//
农历年份
year
=
iYear;
yearCyl
=
iYear
-
1864
;
leapMonth
=
leapMonth(iYear);
//
闰哪个月,1-12
leap
=
false
;
//
用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
int
iMonth, daysOfMonth
=
0
;
for
(iMonth
=
1
; iMonth
<
13
&&
offset
>
0
; iMonth
++
)
{
//
闰月
if
(leapMonth
>
0
&&
iMonth
==
(leapMonth
+
1
)
&&
!
leap)
{
--
iMonth;
leap
=
true
;
daysOfMonth
=
leapDays(year);
}
else
daysOfMonth
=
monthDays(year, iMonth);
offset
-=
daysOfMonth;
//
解除闰月
if
(leap
&&
iMonth
==
(leapMonth
+
1
)) leap
=
false
;
if
(
!
leap) monCyl
++
;
}
//
offset为0时,并且刚才计算的月份是闰月,要校正
if
(offset
==
0
&&
leapMonth
>
0
&&
iMonth
==
leapMonth
+
1
)
{
if
(leap)
{
leap
=
false
;
}
else
{
leap
=
true
;
--
iMonth;
--
monCyl;
}
}
//
offset小于0时,也要校正
if
(offset
<
0
)
{
offset
+=
daysOfMonth;
--
iMonth;
--
monCyl;
}
month
=
iMonth;
day
=
offset
+
1
;
}
public
static
String getChinaDayString(
int
day)
{
String chineseTen[]
=
{
"
初
"
,
"
十
"
,
"
廿
"
,
"
卅
"
}
;
int
n
=
day
%
10
==
0
?
9
: day
%
10
-
1
;
if
(day
>
30
)
return
""
;
if
(day
==
10
)
return
"
初十
"
;
else
return
chineseTen[day
/
10
]
+
chineseNumber[n];
}
public
String toString()
{
return
year
+
"
年
"
+
(leap
?
"
闰
"
:
""
)
+
chineseNumber[month
-
1
]
+
"
月
"
+
getChinaDayString(day);
}
public
static
void
main(String[] args)
throws
ParseException
{
Calendar today
=
Calendar.getInstance();
today.setTime(chineseDateFormat.parse(
"
2003年1月1日
"
));
Lunar lunar
=
new
Lunar(today);
System.out.println(
"
北京时间:
"
+
chineseDateFormat.format(today.getTime())
+
"
农历
"
+
lunar);
}
}
posted on 2007-01-04 19:12
aaabbb 阅读(2586)
评论(3) 编辑 收藏 所属分类:
java