1.农历对照数据集
/** * 1900年1月31日对应农历正月初一 * 数据17位长度(二进制),最高位表示闰月的大小和大小 30, 小 29,例:((LunarDates[0]) >> 16 & 0x01) > 0 ? 30 : 29 * 第16 至 5 位 表示 1-12 月天数,((LunarDates[0]) >> [15~4] & 0x01) > 0 ? 30 : 29 * 第4 至 1 位 表示 闰那个月, 0表示不闰月 LunarDates[0] & 0x0f * **/ private static final int[] LunarDates = new int[]{ 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,0x0A5B0,0x14573,0x052B0,0x0A9A8,0x0E950,0x06AA0, 0x0AEA6,0x0AB50,0x04B60,0x0AAE4,0x0A570,0x05260,0x0F263,0x0D950,0x05B57,0x056A0, 0x096D0,0x04DD5,0x04AD0,0x0A4D0,0x0D4D4,0x0D250,0x0D558,0x0B540,0x0B6A0,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, 0x14B63};
二、公历转农历日期:
public static int[] getLunarDateFromDate(Date date){ int[] lunarDate = new int[3]; Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); if (year < 1900 || year > 2050)return lunarDate; else if (year == 1900){ int month = calendar.get(Calendar.MONTH); if (month == 0)return lunarDate; } long sumDay = sumDay(date); return computeLunarDate(sumDay); }
/** * 计算距离1900-01-31的总天数 * * @param date 参与计算的日期 * **/ private static long sumDay(Date date){ Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); int startYear = 1901; long day = 365 -30; if (startYear == year){ day = calendar.get(Calendar.DAY_OF_YEAR); }else { while (year > startYear){ if ((startYear % 4 == 0 && startYear % 100 != 0) || startYear % 400 == 0){ day = 366; }else { day = 365; } startYear ; } day = calendar.get(Calendar.DAY_OF_YEAR); } return day; }
/** * 根据天数差计算农历日期 * @param sumDay 总天数为1900-01-31 * * @return 返回农历年月日数组, 当月负数表示闰月 * **/ private static int[] computeLunarDate(long sumDay){ int[] lunarDates = new int[3]; long tDay = 0; int lunarDate = 0; for (int i=0;i < LunarDates.length; i ){ lunarDate = LunarDates[i]; int ltd = lunarYearDays(lunarDate); tDay = ltd; if (tDay > sumDay){ tDay = tDay - ltd; lunarDates[0] = 1900 i; break; } } long dt = sumDay - tDay; int yunDays = ((lunarDate >> 16) & 0x01) == 1 ? 30 : 29; int runYue = lunarDate & 0x0f; for (int i = 1;i<13;i ){ int index = 16 - i; int day = ((lunarDate>>index) & 0x01) == 1 ? 30 : 29; if (dt <= day){ lunarDates[1] = i; lunarDates[2] = (int)dt; break; } dt = dt - day; if (runYue == i){ if (dt <= yunDays){ lunarDates[1] = -i; lunarDates[2] = (int)dt; break; } dt = dt - yunDays; } } return lunarDates; }
/** * 农历一年的总天数 * @param lunarDate 农历一年数据 * * **/ private static int lunarYearDays(int lunarDate){ int yunDays = (lunarDate >> 16) & 0x01; int days = 0; for (int b = 15; b > 3; b --){ int day = ((lunarDate >> b) & 0x01) == 1 ? 30 : 29; days = day; } int runYue = lunarDate & 0x0f; if (runYue > 0){ days = yunDays == 1 ? 30 : 29; } return days; }
3.农历日期转公历日期
/** * 农历日期只能转换为公历日期 1900年1月31日 至 2049年12月31日 * 闰月月份为负数,如 润4月 为 -4 * * @param lunarYear 农历年 * @param lunarMonth 农历月 * @param lunarDay 农历日 * **/ public static Date getDateFromLunarDate(@IntRange(from = 1900, to = 2049) int lunarYear, int lunarMonth, int lunarDay){ int year = lunarYear - 100;
int days = 0;
for (int i=0; i< year; i++){
days += lunarYearDays(LunarDates[i]);
}
int lunarDate = LunarDates[year];
int yunDays = ((lunarDate >> 16) & 0x01) == 1 ? 30 : 29;
int runYue = lunarDate & 0x0f;
if (runYue < Math.abs(lunarMonth) && runYue != 0)days += yunDays;
for (int i = 1;i<13;i++){
int index = 16 - i;
int day = ((lunarDate>>index) & 0x01) == 1 ? 30 : 29;
if (lunarMonth > 0){
if (lunarMonth == i){
days += lunarDay;
break;
}else {
days += day;
}
}else {
if (i < -lunarMonth){
days += day;
}else if (i == -lunarDate){
days += day;
days += lunarDay;
break;
}
}
}
int yearDays = 0;//公历初始天数
int[] ymd = new int[3];
for (int i=1900;i<=lunarYear+1;i++){
int day = 365;
if (i%100 == 0){
if (i%400 == 0) day = 366;
}else if (i%4 == 0){
day = 366;
}
if (yearDays + day > days){
ymd[0] = i;
break;
}
yearDays += day;
}
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, ymd[0]);
int cd = days - (yearDays - 30);
calendar.set(Calendar.DAY_OF_YEAR, cd);
return calendar.getTime();
}