「utils」java旧暦util、陽暦転旧暦、アリ符号化規範プラグインはスキャンしたことがある.
9313 ワード
/**
*
* @author guokaige
*
*/
public class LunarSolarConverter {
private static final long MIN_TIME_MILLIS, MAX_TIME_MILLIS;
private static final long YEAR_1900=1900;
private static final long YEAR_1900_MONTH_11=11;
private static final long MONTH_NUM=12;
private static final int MEM_0X8000=0x8000;
private static final int MEM_0X8=0x8;
/**
* (1900-2100 )
* 16 , 2
* 16 , 15 0,( 17 , 1 , )
* 12 12 ,1 ,0
* 4 , , 0110, 6
*/
private final static int[] LUNAR_INFO = {
0x10, 0x4ae0, 0xa570, 0x54d5, 0xd260, 0xd950, 0x16554, 0x56a0, 0x9ad0, 0x55d2,
0x4ae0, 0xa5b6, 0xa4d0, 0xd250, 0x1d255, 0xb540, 0xd6a0, 0xada2, 0x95b0, 0x14977,
0x4970, 0xa4b0, 0xb4b5, 0x6a50, 0x6d40, 0x1ab54, 0x2b60, 0x9570, 0x52f2, 0x4970,
0x6566, 0xd4a0, 0xea50, 0x16a95, 0x5ad0, 0x2b60, 0x186e3, 0x92e0, 0x1c8d7, 0xc950,
0xd4a0, 0x1d8a6, 0xb550, 0x56a0, 0x1a5b4, 0x25d0, 0x92d0, 0xd2b2, 0xa950, 0xb557,
0x6ca0, 0xb550, 0x15355, 0x4da0, 0xa5b0, 0x14573, 0x52b0, 0xa9a8, 0xe950, 0x6aa0,
0xaea6, 0xab50, 0x4b60, 0xaae4, 0xa570, 0x5260, 0xf263, 0xd950, 0x5b57, 0x56a0,
0x96d0, 0x4dd5, 0x4ad0, 0xa4d0, 0xd4d4, 0xd250, 0xd558, 0xb540, 0xb6a0, 0x195a6,
0x95b0, 0x49b0, 0xa974, 0xa4b0, 0xb27a, 0x6a50, 0x6d40, 0xaf46, 0xab60, 0x9570,
0x4af5, 0x4970, 0x64b0, 0x74a3, 0xea50, 0x6b58, 0x5ac0, 0xab60, 0x96d5, 0x92e0,
0xc960, 0xd954, 0xd4a0, 0xda50, 0x7552, 0x56a0, 0xabb7, 0x25d0, 0x92d0, 0xcab5,
0xa950, 0xb4a0, 0xbaa4, 0xad50, 0x55d9, 0x4ba0, 0xa5b0, 0x15176, 0x52b0, 0xa930,
0x7954, 0x6aa0, 0xad50, 0x5b52, 0x4b60, 0xa6e6, 0xa4e0, 0xd260, 0xea65, 0xd530,
0x5aa0, 0x76a3, 0x96d0, 0x26fb, 0x4ad0, 0xa4d0, 0x1d0b6, 0xd250, 0xd520, 0xdd45,
0xb5a0, 0x56d0, 0x55b2, 0x49b0, 0xa577, 0xa4b0, 0xaa50, 0x1b255, 0x6d20, 0xada0,
0x14b63, 0x9370, 0x49f8, 0x4970, 0x64b0, 0x168a6, 0xea50, 0x6aa0, 0x1a6c4, 0xaae0,
0x92e0, 0xd2e3, 0xc960, 0xd557, 0xd4a0, 0xda50, 0x5d55, 0x56a0, 0xa6d0, 0x55d4,
0x52d0, 0xa9b8, 0xa950, 0xb4a0, 0xb6a6, 0xad50, 0x55a0, 0xaba4, 0xa5b0, 0x52b0,
0xb273, 0x6930, 0x7337, 0x6aa0, 0xad50, 0x14b55, 0x4b60, 0xa570, 0x54e4, 0xd160,
0xe968, 0xd520, 0xdaa0, 0x16aa6, 0x56d0, 0x4ae0, 0xa9d4, 0xa2d0, 0xd150, 0xf252,
0xd520
};
private final static String[] LUNAR_MONTH_ARRAYS = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
private final static String[] LUNAR_DAY_ARRAYS = {" ", " ", " ", " "};
private final static String[] NUMBERS = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
static {
Calendar calendar = Calendar.getInstance();
// 1901-1-1 1900-11-11
calendar.set(1901, 0, 1, 0, 0, 0);
MIN_TIME_MILLIS = calendar.getTimeInMillis();
// 2100-12-31 2100-12-1
calendar.set(2100, 11, 31, 23, 59, 59);
MAX_TIME_MILLIS = calendar.getTimeInMillis();
}
/**
*
*
* @param timeInMillis
* @return Lunar
*/
public static Lunar converterDate(long timeInMillis) {
if (timeInMillis < MIN_TIME_MILLIS || timeInMillis > MAX_TIME_MILLIS) {
throw new RuntimeException(" ,-->minDate:1900-1-1 maxDate 2100-12-31");
}
Lunar lunar = new Lunar();
//
long offset = (timeInMillis - MIN_TIME_MILLIS) / (24 * 60 * 60 * 1000);
// 1900 ,
int lunarYear = 1900;
while (true) {
int daysInLunarYear = getLunarYearDays(lunarYear);
if (offset > daysInLunarYear) {
offset -= daysInLunarYear;
lunarYear++;
} else {
break;
}
}
lunar.year = lunarYear;
//
int leapMonth = getLunarLeapMonth(lunarYear);
//
lunar.leapMonth = leapMonth;
// ,
int lunarMonth = lunarYear == 1900 ? 11 : 1;
int daysInLunarMonth;
// , ,
while (true) {
// ,
if (lunarMonth == leapMonth) {
daysInLunarMonth = getLunarDays(lunarYear, lunarMonth);
// >
if (offset > daysInLunarMonth) {
//
offset -= daysInLunarMonth;
// >
if (offset > getLunarLeapDays(lunarYear)) {
//
offset -= getLunarLeapDays(lunarYear);
// +1
lunarMonth++;
} else {
//
lunarMonth = lunarYear;
break;
}
} else {
break;
}
} else { //
daysInLunarMonth = getLunarDays(lunarYear, lunarMonth);
// >
if (offset > daysInLunarMonth) {
//
offset -= daysInLunarMonth;
lunarMonth++;// +1
} else {
break;
}
}
}
lunar.month = lunarMonth;
lunar.day = (lunarYear == 1900 && lunarMonth == 11) ? (int) Math.abs(-offset + -11) : (int) offset;
return lunar;
}
/**
*
*
* @param lunarYear
* @return
*/
private static int getLunarYearDays(int lunarYear) {
if (lunarYear == YEAR_1900) {
//1900 48
return 48;
}
// , 12 * 29 = 348
int daysInLunarYear = 348;
// 12
for (int i = MEM_0X8000; i > MEM_0X8; i >>= 1) {
//
daysInLunarYear += ((LUNAR_INFO[lunarYear - 1900] & i) != 0) ? 1 : 0;
}
//
daysInLunarYear += getLunarLeapDays(lunarYear);
return daysInLunarYear;
}
/**
*
*
* @param lunarYear
* @return , 0 ( )
*/
private static int getLunarLeapDays(int lunarYear) {
// 17 , 1 , (2017/2055)
// , 0
return getLunarLeapMonth(lunarYear) > 0 ? ((LUNAR_INFO[lunarYear - 1900] & 0x10000) > 0 ? 30 : 29) : 0;
}
/**
*
*
* @param lunarYear
* @return , , 0
*/
private static int getLunarLeapMonth(int lunarYear) {
// 4
int leapMonth = LUNAR_INFO[lunarYear - 1900] & 0xf;
leapMonth = (leapMonth == 0xf ? 0 : leapMonth);
// 12
if (leapMonth > MONTH_NUM) {
throw new RuntimeException(lunarYear + " ,lunarYear:" + Integer.toBinaryString(LUNAR_INFO[lunarYear - 1900]));
}
return leapMonth;
}
/**
*
*
* @param lunarYear
* @return
*/
private static int getLunarDays(int lunarYear, int month) {
if (lunarYear == YEAR_1900 && month == YEAR_1900_MONTH_11) {
//1900 11 18
return 18;
}
return (LUNAR_INFO[lunarYear - 1900] & (0x10000 >> month)) != 0 ? 30 : 29;
}
public static class Lunar {
public int year;
public int month;
public int day;
public int leapMonth;
public String getMonth() {
return month > LUNAR_MONTH_ARRAYS.length ? " " + LUNAR_MONTH_ARRAYS[leapMonth - 1] : LUNAR_MONTH_ARRAYS[month - 1];
}
public String getDay() {
int result = day / 10;
return LUNAR_DAY_ARRAYS[(result == 1 && day % 10 == 0) ? result - 1 : result] +
(day % 10 == 0 ? NUMBERS[NUMBERS.length - 1] : NUMBERS[Math.abs(day - result * 10) - 1]);
}
@Override
public String toString() {
return "Lunar{" +
" =" + year +
", =" + month +
", =" + day +
", =" + leapMonth +
", / :" + getMonth() + " " + getDay() +
'}';
}
}
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
System.out.println("DATE:" + calendar.get(Calendar.DATE));
Lunar lunar=LunarSolarConverter.converterDate(calendar.getTimeInMillis());
System.out.println(lunar.getDay());
}
}