写了一个工具类DateTransfer,提供在1900-2099年的以下功能:
1.公历转换为农历:Gregorian2Lunar
2.农历转换为公历:Lunar2Gregorian
3.公历日期获取星期:GetDayOfWeek
4.农历日期获取星期:getWeekDayOfLunarDate
5.获取指定农历年月的一个月的字符串数组:LunarCalendar_GetMonthDateNames
6.获取指定农历年的所有月份的字符串数组:LunarCalendar_allMonths
1.公历转换为农历:Gregorian2Lunar
2.农历转换为公历:Lunar2Gregorian
3.公历日期获取星期:GetDayOfWeek
4.农历日期获取星期:getWeekDayOfLunarDate
5.获取指定农历年月的一个月的字符串数组:LunarCalendar_GetMonthDateNames
6.获取指定农历年的所有月份的字符串数组:LunarCalendar_allMonths
这个工具类写好后用中华万年例测试了一些时间,都是对的,中华万年历的可以看到1900-2070(怎么对得起万年的称号,而且有bug,滑动日期到1900年3月应用就崩溃了)
其实是开发一个timepicker日历选择控件,为了设置农历生日,支持100年总共两百年应该够用了 吧,控件工程有时间传到github上分享给大家
以下源代码,使用的时候注意在开头加上你的package名:
<span style="font-size:18px;">import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
/**
* 公历与农历转换的支持库,当前农历支持从1900~2099之间的转换。
*/
public class DateTransfer {
/**
* 将支持的年份 支持转换的最小农历年份
*/
public static final int MIN_YEAR = 1900;
/**
* 支持转换的最大农历年份
*/
public static final int MAX_YEAR = 2099;
/**
* 用来表示1900年到2099年间农历年份的相关信息,共24位bit的16进制表示,其中: 1.
* 前4位表示该年闰哪个月; 2. 5-17位表示农历年份13个月的大小月分布,0表示小,1表示大; 3.
* 最后7位表示农历年首(正月初一)对应的公历日期。 以2014年的数据0x955ABF为例说明: 1001 0101 0101
* 1010 1011 1111 闰九月 农历正月初一对应公历1月31号
*/
private static final int LUNAR_INFO[] = { 0x84B6BF,/* 1900 */
0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D,
0x09AD42, 0x24AEB6, 0x04AE4A,/* 1901-1910 */
0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43,
0x296D37, 0x095B4B, 0x749BC1, 0x049754,/* 1911-1920 */
0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D,
0x095742, 0x2497B7, 0x04974A, 0x664B3E,/* 1921-1930 */
0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738,
0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48,/* 1931-1940 */
0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42,
0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51,/* 1941-1950 */
0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C,
0x8A953F, 0x0E9552, 0x06AA48, 0x6AD53C,/* 1951-1960 */
0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335,
0x0D9549, 0x75AABE, 0x056A51, 0x096D46,/* 1961-1970 */
0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF,
0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50,/* 1971-1980 */
0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449,
0x6ADA3D, 0x0AB651, 0x095746, 0x5497BB,/* 1981-1990 */
0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53,
0x0AB647, 0x5936BC, 0x092E50, 0x0C9645,/* 1991-2000 */
0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD,
0x025D52, 0x092D47, 0x5C95BA, 0x0A954E,/* 2001-2010 */
0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48,
0x652BBC, 0x052B50, 0x0A9345, 0x474AB9,/* 2011-2020 */
0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x6a573D, 0x0A4E51,
0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43,/* 2021-2030 */
0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC,
0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C,/* 2031-2040 */
0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546,
0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37,/* 2041-2050 */
0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F,
0x06AA44, 0x4AB638, 0x0AAE4C, 0x092E42,/* 2051-2060 */
0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA,
0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B,/* 2061-2070 */
0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45,
0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6,/* 2071-2080 */
0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E,
0x0A5743, 0x452738, 0x0D264A, 0x8E933E,/* 2081-2090 */
0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9,
0x0A4D4C, 0x0D1541, 0x2D92B5 /* 2091-2099 */
};
/** 农历日期名称 */
static String Lunar_DayName;
/** 农历年份名称 */
static String Lunar_MonName;
static {
// Lunar_MonName = " 正 二 三 四 五 六 七 八 九 十 冬 腊";//空格在前面,下面是字符的UTF-8编码
Lunar_MonName = "\u0020\u6b63\u0020\u4e8c\u0020\u4e09\u0020\u56db\u0020\u4e94\u0020\u516d\u0020\u4e03\u0020\u516b\u0020\u4e5d\u0020\u5341\u0020\u51ac\u0020\u814a";
// Lunar_DayName
// ="初一初二初三初四初五初六初七初八初九初十十一十二十三十四十五十六十七十八十九二十廿一廿二廿三廿四廿五廿六廿七廿八廿九三十";
Lunar_DayName = "\u521d\u4e00\u521d\u4e8c\u521d\u4e09\u521d\u56db\u521d\u4e94\u521d\u516d\u521d\u4e03\u521d\u516b\u521d\u4e5d\u521d\u5341\u5341\u4e00\u5341\u4e8c\u5341\u4e09\u5341\u56db\u5341\u4e94\u5341\u516d\u5341\u4e03\u5341\u516b\u5341\u4e5d\u4e8c\u5341\u5eff\u4e00\u5eff\u4e8c\u5eff\u4e09\u5eff\u56db\u5eff\u4e94\u5eff\u516d\u5eff\u4e03\u5eff\u516b\u5eff\u4e5d\u4e09\u5341";
}
/**
* 1900年到2099年每年中的月天数信息,阴历每月只能是29或30天,
* 一年用12(或13)个二进制位表示,对应位为1表30天,否则为29天
*/
static final int[] Lunar_LunarMonthDay = {
// 1900
0x4B68,
// 1901-1910
0x4AE0,
0xA570,
0x5268,
0xD260,
0xD950,
0x6AA8,
0x56A0,
0x9AD0,
0x4AE8,
0x4AE0,
// 1911-1920
0xA4D8,
0xA4D0,
0xD250,
0xD528,
0xB540,
0xD6A0,
0x96D0,
0x95B0,
0x49B8,
0x4970,
// 1921-1930
0xA4B0,
0xB258,
0x6A50,
0x6D40,
0xADA8,
0x2B60,
0x9570,
0x4978,
0x4970,
0x64B0,
//1931-1940
0xD4A0,
0xEA50,
0x6D48,
0x5AD0,
0x2B60,
0x9370,
0x92E0,
0xC968,
0xC950,
0xD4A0,
// 1941-1949
0xDA50,
0xB550,
0x56A0,
0xAAD8,
0x25D0,
0x92D0,
0xC958,
0xA950,
0xB4A8,
// 1950
0x6ca0,
0xb550,
0x55a8,
0x4da0,
0xa5b0,
0x52b8,
0x52b0,
0xa950,
0xe950,
0x6aa0,
// 1960
0xad50,
0xab50,
0x4b60,
0xa570,
0xa570,
0x5260,
0xe930,
0xd950,
0x5aa8,
0x56a0,
// 1970
0x96d0,
0x4ae8,
0x4ad0,
0xa4d0,
0xd268,
0xd250,
0xd528,
0xb540,
0xb6a0,
0x96d0,
// 1980
0x95b0,
0x49b0,
0xa4b8,
0xa4b0,
0xb258,
0x6a50,
0x6d40,
0xada0,
0xab60,
0x9570,
// 1990
0x4978,
0x4970,
0x64b0,
0x6a50,
0xea50,
0x6b28,
0x5ac0,
0xab60,
0x9368,
0x92e0,
// 2000
0xc960,
0xd4a8,
0xd4a0,
0xda50,
0x5aa8,
0x56a0,
0xaad8,
0x25d0,
0x92d0,
0xc958,
// 2010
0xa950, 0xb4a0,
0xb550,
0xad50,
0x55a8,
0x4ba0,
0xa5b0,
0x52b8,
0x52b0,
0xa930,
// 2020
0x74a8, 0x6aa0, 0xad50,
0x4da8,
0x4b60,
0xa570,
0xa4e0,
0xd260,
0xe930,
0xd530,
// 2030
0x5aa0, 0x6b50, 0x96d0, 0x4ae8,
0x4ad0,
0xa4d0,
0xd258,
0xd250,
0xd520,
0xdaa0,
// 2040
0xb5a0,
0x56d0,
0x4ad8,
0x49b0,
0xa4b8,
0xa4b0,
0xaa50,
0xb528,
0x6d20,
0xada0,
// 2050
0x55b0,
// 2051-2060
0x9370, 0x4978, 0x4970, 0x64B0, 0x6A50, 0xEA50,
0x6AA0,
0xAB60,
0xAAE0,
0x92E0,
// 2061-2070
0xC970, 0xC960, 0xD4A8, 0xD4A0, 0xDA50, 0x5AA8, 0x56A0,
0xA6D0,
0x52E8,
0x52D0,
// 2071-2080
0xA958, 0xA950, 0xB4A0, 0xB550, 0xAD50, 0x55A0, 0xA5D0, 0xA5B0,
0x52B0,
0xA938,
// 2081-2090
0x6930, 0x7298, 0x6AA0, 0xAD50, 0x4DA8, 0x4B60, 0xA570, 0x5270,
0xD260, 0xE930,
// 2091-2099
0xD520, 0xDAA0, 0x6B50, 0x56D0, 0x4AE0, 0xA4E8, 0xA4D0, 0xD150,
0xD928 };
/**
* Lunar_LunarMonth存放的是1900~2099年的闰月的月份,没有为0
*/
static final int[] Lunar_LunarMonth = { 0x8, /* 1900 */
0x0, 0x0, 0x5, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2, 0x0,/* 1901-1910 */
0x6, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2, 0x0, 0x7, 0x0,/* 1911-1920 */
0x0, 0x5, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2, 0x0, 0x6,/* 1921-1930 */
0x0, 0x0, 0x5, 0x0, 0x0, 0x3, 0x0, 0x7, 0x0, 0x0,/* 1931-1940 */
0x6, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2, 0x0, 0x7, 0x0,/* 1941-1950 */
0x0, 0x5, 0x0, 0x0, 0x3, 0x0, 0x8, 0x0, 0x0, 0x6,/* 1951-1960 */
0x0, 0x0, 0x4, 0x0, 0x0, 0x3, 0x0, 0x7, 0x0, 0x0,/* 1961-1970 */
0x5, 0x0, 0x0, 0x4, 0x0, 0x8, 0x0, 0x0, 0x6, 0x0,/* 1971-1980 */
0x0, 0x4, 0x0, 0xA, 0x0, 0x0, 0x6, 0x0, 0x0, 0x5,/* 1981-1990 */
0x0, 0x0, 0x3, 0x0, 0x8, 0x0, 0x0, 0x5, 0x0, 0x0,/* 1991-2000 */
0x4, 0x0, 0x0, 0x2, 0x0, 0x7, 0x0, 0x0, 0x5, 0x0,/* 2001-2010 */
0x0, 0x4, 0x0, 0x9, 0x0, 0x0, 0x6, 0x0, 0x0, 0x4,/* 2011-2020 */
0x0, 0x0, 0x2, 0x0, 0x6, 0x0, 0x0, 0x5, 0x0, 0x0,/* 2021-2030 */
0x3, 0x0, 0xB, 0x0, 0x0, 0x6, 0x0, 0x0, 0x5, 0x0,/* 2031-2040 */
0x0, 0x2, 0x0, 0x7, 0x0, 0x0, 0x5, 0x0, 0x0, 0x3,/* 2041-2050 */
0x0, 0x8, 0x0, 0x0, 0x6, 0x0, 0x0, 0x4, 0x0, 0x0,/* 2051-2060 */
0x3, 0x0, 0x7, 0x0, 0x0, 0x5, 0x0, 0x0, 0x4, 0x0,/* 2061-2070 */
0x8, 0x0, 0x0, 0x6, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3,/* 2071-2080 */
0x0, 0x7, 0x0, 0x0, 0x5, 0x0, 0x0, 0x4, 0x0, 0x8,/* 2081-2090 */
0x0, 0x0, 0x6, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2 /* 2091-2099 */
};
/**
* 每年春节对应的公历的哪一天
*/
static final int[] Lunar_SpringMonthDay = {
131, 219, 208, 129, 216, 204,125, 213, 202, 122, /* 1900-1909 */
210, 130, 218, 206, 126, 214, 203, 123, 211, 201, /* 1910-1919 */
220, 208, 128, 216, 205, 124, 213, 202, 123, 210, /* 1920-1929 */
130, 217, 206, 126, 214, 204, 124, 211, 131, 219, /* 1930-1939 */
208, 127, 215, 205, 125, 213, 202, 122, 210, 129, /* 1940-1949 */
217, 206, 127, 214, 203, 124, 212, 131, 218, 208, /* 1950-1959 */
128, 215, 205, 125, 213, 202, 121, 209, 130, 217, /* 1960-1969 */
206, 127, 215, 203, 123, 211, 131, 218, 207, 128, /* 1970-1979 */
216, 205, 125, 213, 202, 220, 209, 129, 217, 206, /* 1980-1989 */
127, 215, 204, 123, 210, 131, 219, 207, 128, 216, /* 1990-1999 */
205, 124, 212, 201, 122, 209, 129, 218, 207, 126, /* 2000-2009 */
214, 203, 123, 210, 131, 219, 208, 128, 216, 205, /* 2010-2019 */
125, 212, 201, 122, 210, 129, 217, 206, 126, 213, /* 2020-2029 */
203, 123, 211, 131, 219, 208, 128, 215, 204, 124, /* 2030-2039 */
212, 201, 122, 210, 130, 217, 206, 126, 214, 202, /* 2040-2049 */
123, 211, 201, 219, 208, 128, 215, 204, 124, 212, /* 2050-2059 */
202, 121, 209, 129, 217, 205, 126, 214, 203, 123, /* 2060-2069 */
211, 131, 219, 207, 127, 215, 205, 124, 212, 202, /* 2070-2079 */
122, 209, 129, 217, 206, 126, 214, 203, 124, 210, /* 2080-2089 */
130, 218, 207, 127, 215, 205, 125, 212, 201, 121, /* 2090-2099 */
};
/**
* 判断是否是闰年
* @param y 年份
* @return true表示是闰年, false表示不是
*/
private static boolean IsLeapYear(int y) {
return (((y % 400) == 0) || (((y % 4) == 0) && ((y % 100) != 0)));
}
/**
* 获取可转换的农历的起始年份
* @return 起始农历年份
*/
public static int getLunarStartYear() {
return MIN_YEAR;
}
/**
* 获取可转换的农历的截止年份
* @return 截止农历年份
*/
public static int getLunarEndYear() {
return MAX_YEAR;
}
/**
* 根据公历日期, 获取农历日期
* @param date 要转换的公历日期
* @param lunarP 返回的农历日期
* @return -1表示超出判断边界, 0表示成功
*/
public static int Gregorian2Lunar(Date_T date, Lunar_Date_T lunarP) {
if (date.wYear < 1900 || date.byDay > 31 || date.byMonth > 12) {
return -1;
}
Date baseDate = new GregorianCalendar(1900, 0, 31).getTime();
Date objDate = new GregorianCalendar(date.wYear, date.byMonth - 1,
date.byDay).getTime();
int offset = (int) ((objDate.getTime() - baseDate.getTime()) / 86400000L);
// 用offset减去每农历年的天数计算当天是农历第几天
// iYear最终结果是农历的年份, offset是当年的第几天
int iYear, daysOfYear = 0;
for (iYear = MIN_YEAR; iYear <= MAX_YEAR && offset > 0; iYear++) {
daysOfYear = daysInLunarYear(iYear);
offset -= daysOfYear;
}
if (offset < 0) {
offset += daysOfYear;
iYear--;
}
// 农历年份
lunarP.wNian = iYear;
int leapMonth = leapMonth(iYear); // 闰哪个月,1-12
boolean isLeap = false;
// 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
int iMonth, daysOfMonth = 0;
for (iMonth = 1; iMonth <= 13 && offset > 0; iMonth++) {
daysOfMonth = daysInLunarMonth(iYear, iMonth);
offset -= daysOfMonth;
}
// 当前月超过闰月,要校正
if (leapMonth != 0 && iMonth > leapMonth + 1) {
--iMonth;
if (iMonth == leapMonth + 1) {
isLeap = true;
}
}
// offset小于0时,也要校正
if (offset < 0) {
offset += daysOfMonth;
--iMonth;
}
lunarP.wRunYue = leapMonth;
lunarP.wYue = iMonth;
lunarP.wRi = offset + 1;
if (leapMonth != 0)
lunarP.bRunNian = true;
else
lunarP.bRunNian = false;
// 月
if (isLeap) {
lunarP.szYueText += "\u95f0";// 闰 == \u95f0
}
String strTemp = Lunar_MonName.substring((lunarP.wYue - 1) * 2,
((lunarP.wYue - 1) * 2) + 2);
lunarP.szYueText += strTemp.substring(strTemp.indexOf(" ") + 1);
// 日
lunarP.szRiText += Lunar_DayName.substring((lunarP.wRi - 1) * 2,
((lunarP.wRi - 1) * 2) + 2);
if (leapMonth != 0) {
if ((lunarP.wYue > leapMonth)
|| (lunarP.wYue == leapMonth && isLeap)) {
lunarP.wYue++;
}
}
return 0;
}
/**
* 农历转换为公历
* @param tLCDate 农历年月日
* @param tGCDate 公历日期
* @return -1表示超过转换边界 ,0 表示成功
*/
public static int Lunar2Gregorian(Date_T tLCDate,
Date_T tGCDate) {
if (tLCDate.wYear < 1900) {
return -1;
}
int tian = 0;
int i;
int SpringMonth;
int SpringDay;
int LunarMonth;
int flag;
int[] DayOfMon = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
LunarMonth = tLCDate.byMonth;
if (IsLeapYear(tLCDate.wYear)) {
DayOfMon[1] = 29;
}
// 公历的月日
SpringMonth = Lunar_SpringMonthDay[tLCDate.wYear - 1900] / 100;
SpringDay = Lunar_SpringMonthDay[tLCDate.wYear - 1900] % 100;
flag = 0x8000;
for (i = 1; i < LunarMonth; i++) {
tian = ((Lunar_LunarMonthDay[tLCDate.wYear - 1900] & flag) != 0) ? 30
: 29;
if ((SpringDay + tian) > (int) DayOfMon[(SpringMonth - 1) % 12]) {
SpringDay = (SpringDay + tian)
- DayOfMon[(SpringMonth - 1) % 12];
SpringMonth++;
} else {
SpringDay += tian;
}
flag >>= 1;
}
if ((SpringDay + tLCDate.byDay - 1) > (int) DayOfMon[(SpringMonth - 1) % 12]) {
SpringDay = (SpringDay + tLCDate.byDay)
- DayOfMon[(SpringMonth - 1) % 12] - 1;
SpringMonth++;
} else {
SpringDay = (SpringDay + tLCDate.byDay) - 1;
}
if (SpringMonth > 12) {
SpringMonth -= 12;
tGCDate.wYear = tLCDate.wYear + 1;
} else {
tGCDate.wYear = tLCDate.wYear;
}
tGCDate.byMonth = SpringMonth;
tGCDate.byDay = SpringDay;
return 0;
}
/**
* @param year 将要计算的年份
* @return 返回传入年份的总天数
*/
private static int daysInLunarYear(int year) {
int i, sum = 348;
if (leapMonth(year) != 0) {
sum = 377;
}
int monthInfo = LUNAR_INFO[year - MIN_YEAR] & 0x0FFF80;
for (i = 0x80000; i > 0x7; i >>= 1) {
if ((monthInfo & i) != 0)
sum += 1;
}
return sum;
}
/**
* @param year 将要计算的年份
* @return 传回农历 year年闰哪个月1-12, 没闰传回 0
*/
private static int leapMonth(int year) {
return (int) ((LUNAR_INFO[year - MIN_YEAR] & 0xF00000)) >> 20;
}
/**
* 传回农历 year年month月的总天数,总共有13个月包括闰月
* @param year 将要计算的年份
* @param month 将要计算的月份
* @return 传回农历 year年month月的总天数
*/
private static int daysInLunarMonth(int year, int month) {
if ((LUNAR_INFO[year - MIN_YEAR] & (0x100000 >> month)) == 0)
return 29;
else
return 30;
}
/**
* 获取农历年的所有月份的字符串数组
* @param lunarYear 农历年份
* @return 月份字符串数组
*/
public static synchronized ArrayList<String> LunarCalendar_allMonths(
int lunarYear) {
ArrayList<String> allMonths = new ArrayList<String>();
if (lunarYear < 1900) {
return allMonths;
}
allMonths.add("\u6b63\u6708");
allMonths.add("\u4e8c\u6708");
allMonths.add("\u4e09\u6708");
allMonths.add("\u56db\u6708");
allMonths.add("\u4e94\u6708");
allMonths.add("\u516d\u6708");
allMonths.add("\u4e03\u6708");
allMonths.add("\u516b\u6708");
allMonths.add("\u4e5d\u6708");
allMonths.add("\u5341\u6708");
allMonths.add("\u51ac\u6708");
allMonths.add("\u814a\u6708");
int RunYue;
RunYue = Lunar_LunarMonth[lunarYear - 1900];
// 正月二月 三月 四月 五月 六月 七 月八月 九月 十月 冬月 腊月
if (0 == RunYue) {
return allMonths;
} else {
String strTemp = Lunar_MonName.substring((RunYue - 1) * 2,
((RunYue - 1) * 2) + 2);
allMonths.add(RunYue,
"\u95f0" + strTemp.substring(strTemp.indexOf(" ") + 1)
+ "\u6708");
}
return allMonths;
}
/**
* 获取指定农历年月的一个月的字符串数组
* @param year 农历年
* @param month 农历月
* @return 指定农历一个月的字符串
*/
public static ArrayList<String> LunarCalendar_GetMonthDateNames(int year,
int month) {
ArrayList<String> monthDateNames = new ArrayList<String>();
if (year < 1900) {
return monthDateNames;
}
int flag = 0x8000;
int i = 0;
for (i = 1; i < month; i++) {
flag >>= 1;
}
int tian = ((Lunar_LunarMonthDay[year - 1900] & flag) != 0) ? 30 : 29;
for (i = 0; i < tian; i++) {
monthDateNames.add(Lunar_DayName.substring(i * 2, i * 2 + 2));
}
return monthDateNames;
}
/**
* 获取星期
* @param tLCDate 农历的年,月(1~13),日
* @return 星期信息(0~6)
*/
public static int getWeekDayOfLunarDate(Date_T tLCDate) {
// 农历转公历,公历转星期
if (tLCDate.wYear < 1900) {
return -1;
}
Date_T tGCDate = new Date_T();
int num = LunarCalendar_GetGregorianCalendarDate(tLCDate, tGCDate);
if (num == 0) {
return GetDayOfWeek(tGCDate);
}
return -1;
}
/**
* 公历日期获取星期信息
* @param pDate 公历日期
* @return 星期信息(0~6)
*/
private static int GetDayOfWeek(Date_T pDate) {
long DayOfWeek = -1;
long century = 0;
long year = pDate.wYear;
long month = pDate.byMonth;
long day = pDate.byDay;
if (!IsDateValid(pDate)) {
return -1;
}
/**
* 蔡勒公式(Zeller's Formula) W = [C/4] - 2*C + y + [y/4] + [13 * (M+1) / 5]
* + d - 1 C是世纪数减一即年份前2位,y是年份后两位,M是月份,d是日数。
* 1月和2月要按上一年的13月和14月来算,这时C和y均按上一年取值。
*/
if ((1 == pDate.byMonth) || (2 == pDate.byMonth)) {
year -= 1;
month += 12;
}
century = year / 100;
year %= 100;
DayOfWeek = ((century / 4) - (2 * century) + year + (year / 4)
+ ((13 * (month + 1)) / 5) + day) - 1;
DayOfWeek = (DayOfWeek + 700) % 7; // 加上700保证余数一定是整数
return (int) DayOfWeek;
}
/**
* 判断当前的日期(byDay)是否超出了当前月的天数DayNumOfMonth
* @param pDate 年月信息 内部调用
*/
private static boolean IsDateValid(Date_T pDate) {
long DayNumOfMonth = GetDayNumOfMonth(pDate);
if ((0 == DayNumOfMonth) || ((long) pDate.byDay > DayNumOfMonth)) {
return false;
}
return true;
}
/**
* 获取某个月的天数
* @param pDate 年月信息
* @return 天数 内部调用
*/
private static long GetDayNumOfMonth(Date_T pDate) {
long[] DayOfMon = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
// 参数检查
if ((1900 > pDate.wYear) || (2099 < pDate.wYear) || (1 > pDate.byMonth)
|| (12 < pDate.byMonth) || (1 > pDate.byDay)
|| (31 < pDate.byDay)) {
return -1;
}
if (IsLeapYear(pDate.wYear)) {
DayOfMon[1] = 29;
}
return DayOfMon[pDate.byMonth - 1];
}
/**
* 日期信息
*/
static public class Date_T {
public int wYear;
public int byMonth;
public int byDay;
}
/**
* 农历信息
*/
static public class Lunar_Date_T {
public int wNian; // 农历年
public int wYue; // 农历月
public int wRi; // 农历日
int wJieQi1; // 节气1
int wJieQi2; // 节气2
boolean bRunNian; // 是否闰年
public int wRunYue; // 该闰年的闰月
public String szYueText = ""; // 农历月
public String szRiText = ""; // 农历日
}
}
</span>