228 lines
4.8 KiB
Java
228 lines
4.8 KiB
Java
package com.nlf.calendar;
|
||
|
||
import com.nlf.calendar.util.LunarUtil;
|
||
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 农历月
|
||
*
|
||
* @author 6tail
|
||
*/
|
||
public class LunarMonth {
|
||
|
||
/**
|
||
* 农历年
|
||
*/
|
||
private final int year;
|
||
|
||
/**
|
||
* 农历月:1-12,闰月为负数,如闰2月为-2
|
||
*/
|
||
private final int month;
|
||
|
||
/**
|
||
* 天数,大月30天,小月29天
|
||
*/
|
||
private final int dayCount;
|
||
|
||
/**
|
||
* 初一的儒略日
|
||
*/
|
||
private final double firstJulianDay;
|
||
|
||
/**
|
||
* 初始化
|
||
*
|
||
* @param lunarYear 农历年
|
||
* @param lunarMonth 农历月:1-12,闰月为负数,如闰2月为-2
|
||
* @param dayCount 天数
|
||
* @param firstJulianDay 初一的儒略日
|
||
*/
|
||
public LunarMonth(int lunarYear, int lunarMonth, int dayCount, double firstJulianDay) {
|
||
this.year = lunarYear;
|
||
this.month = lunarMonth;
|
||
this.dayCount = dayCount;
|
||
this.firstJulianDay = firstJulianDay;
|
||
}
|
||
|
||
/**
|
||
* 通过农历年月初始化
|
||
*
|
||
* @param lunarYear 农历年
|
||
* @param lunarMonth 农历月:1-12,闰月为负数,如闰2月为-2
|
||
* @return 农历月
|
||
*/
|
||
public static LunarMonth fromYm(int lunarYear, int lunarMonth) {
|
||
return LunarYear.fromYear(lunarYear).getMonth(lunarMonth);
|
||
}
|
||
|
||
/**
|
||
* 获取农历年
|
||
*
|
||
* @return 农历年
|
||
*/
|
||
public int getYear() {
|
||
return year;
|
||
}
|
||
|
||
/**
|
||
* 获取农历月
|
||
*
|
||
* @return 农历月:1-12,闰月为负数,如闰2月为-2
|
||
*/
|
||
public int getMonth() {
|
||
return month;
|
||
}
|
||
|
||
/**
|
||
* 是否闰月
|
||
*
|
||
* @return true/false
|
||
*/
|
||
public boolean isLeap() {
|
||
return month < 0;
|
||
}
|
||
|
||
/**
|
||
* 获取天数
|
||
*
|
||
* @return 天数
|
||
*/
|
||
public int getDayCount() {
|
||
return dayCount;
|
||
}
|
||
|
||
/**
|
||
* 获取初一的儒略日
|
||
*
|
||
* @return 初一的儒略日
|
||
*/
|
||
public double getFirstJulianDay() {
|
||
return firstJulianDay;
|
||
}
|
||
|
||
/**
|
||
* 获取太岁方位
|
||
*
|
||
* @return 方位,如艮
|
||
*/
|
||
public String getPositionTaiSui() {
|
||
String p;
|
||
int m = Math.abs(month) % 4;
|
||
switch (m) {
|
||
case 0:
|
||
p = "巽";
|
||
break;
|
||
case 1:
|
||
p = "艮";
|
||
break;
|
||
case 3:
|
||
p = "坤";
|
||
break;
|
||
default:
|
||
p = LunarUtil.POSITION_GAN[Solar.fromJulianDay(this.getFirstJulianDay()).getLunar().getMonthGanIndex()];
|
||
}
|
||
return p;
|
||
}
|
||
|
||
/**
|
||
* 获取太岁方位描述
|
||
*
|
||
* @return 方位描述,如东北
|
||
*/
|
||
public String getPositionTaiSuiDesc() {
|
||
return LunarUtil.POSITION_DESC.get(getPositionTaiSui());
|
||
}
|
||
|
||
/**
|
||
* 获取月九星
|
||
*
|
||
* @return 九星
|
||
*/
|
||
public NineStar getNineStar() {
|
||
int index = LunarYear.fromYear(year).getZhiIndex() % 3;
|
||
int m = Math.abs(month);
|
||
int monthZhiIndex = (13 + m) % 12;
|
||
int n = 27 - index * 3;
|
||
if (monthZhiIndex < LunarUtil.BASE_MONTH_ZHI_INDEX) {
|
||
n -= 3;
|
||
}
|
||
int offset = (n - monthZhiIndex) % 9;
|
||
return NineStar.fromIndex(offset);
|
||
}
|
||
|
||
@Override
|
||
public String toString() {
|
||
return year + "年" + (isLeap() ? "闰" : "") + LunarUtil.MONTH[Math.abs(month)] + "月(" + dayCount + "天)";
|
||
}
|
||
|
||
/**
|
||
* 获取往后推几个月的阴历月,如果要往前推,则月数用负数
|
||
*
|
||
* @param n 月数
|
||
* @return 阴历月
|
||
*/
|
||
public LunarMonth next(int n) {
|
||
if (0 == n) {
|
||
return LunarMonth.fromYm(year, month);
|
||
} else if (n > 0) {
|
||
int rest = n;
|
||
int ny = year;
|
||
int iy = ny;
|
||
int im = month;
|
||
int index = 0;
|
||
List<LunarMonth> months = LunarYear.fromYear(ny).getMonths();
|
||
while (true) {
|
||
int size = months.size();
|
||
for (int i = 0; i < size; i++) {
|
||
LunarMonth m = months.get(i);
|
||
if (m.getYear() == iy && m.getMonth() == im) {
|
||
index = i;
|
||
break;
|
||
}
|
||
}
|
||
int more = size - index - 1;
|
||
if (rest < more) {
|
||
break;
|
||
}
|
||
rest -= more;
|
||
LunarMonth lastMonth = months.get(size - 1);
|
||
iy = lastMonth.getYear();
|
||
im = lastMonth.getMonth();
|
||
ny++;
|
||
months = LunarYear.fromYear(ny).getMonths();
|
||
}
|
||
return months.get(index + rest);
|
||
} else {
|
||
int rest = -n;
|
||
int ny = year;
|
||
int iy = ny;
|
||
int im = month;
|
||
int index = 0;
|
||
List<LunarMonth> months = LunarYear.fromYear(ny).getMonths();
|
||
while (true) {
|
||
int size = months.size();
|
||
for (int i = 0; i < size; i++) {
|
||
LunarMonth m = months.get(i);
|
||
if (m.getYear() == iy && m.getMonth() == im) {
|
||
index = i;
|
||
break;
|
||
}
|
||
}
|
||
if (rest <= index) {
|
||
break;
|
||
}
|
||
rest -= index;
|
||
LunarMonth firstMonth = months.get(0);
|
||
iy = firstMonth.getYear();
|
||
im = firstMonth.getMonth();
|
||
ny--;
|
||
months = LunarYear.fromYear(ny).getMonths();
|
||
}
|
||
return months.get(index - rest);
|
||
}
|
||
}
|
||
|
||
}
|