package com.nlf.calendar; import com.nlf.calendar.util.LunarUtil; import com.nlf.calendar.util.SolarUtil; import java.util.*; /** * 农历日期 * * @author 6tail */ public class Lunar { /** * 节气表,国标以冬至为首个气令 */ public static final String[] JIE_QI = {"冬至", "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪"}; /** * 实际的节气表 */ public static final String[] JIE_QI_IN_USE = {"DA_XUE", "冬至", "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "DONG_ZHI", "XIAO_HAN", "DA_HAN", "LI_CHUN", "YU_SHUI", "JING_ZHE"}; /** * 农历年 */ private int year; /** * 农历月,闰月为负,即闰2月=-2 */ private int month; /** * 农历日 */ private int day; /** * 对应阳历 */ private final Solar solar; /** * 时对应的天干下标,0-9 */ private int timeGanIndex; /** * 时对应的地支下标,0-11 */ private int timeZhiIndex; /** * 日对应的天干下标,0-9 */ private int dayGanIndex; /** * 日对应的地支下标,0-11 */ private int dayZhiIndex; /** * 日对应的天干下标(八字流派1,晚子时日柱算明天),0-9 */ private int dayGanIndexExact; /** * 日对应的地支下标(八字流派1,晚子时日柱算明天),0-11 */ private int dayZhiIndexExact; /** * 日对应的天干下标(八字流派2,晚子时日柱算当天),0-9 */ private int dayGanIndexExact2; /** * 日对应的地支下标(八字流派2,晚子时日柱算当天),0-11 */ private int dayZhiIndexExact2; /** * 月对应的天干下标(以节交接当天起算),0-9 */ private int monthGanIndex; /** * 月对应的地支下标(以节交接当天起算),0-11 */ private int monthZhiIndex; /** * 月对应的天干下标(最精确的,供八字用,以节交接时刻起算),0-9 */ private int monthGanIndexExact; /** * 月对应的地支下标(最精确的,供八字用,以节交接时刻起算),0-11 */ private int monthZhiIndexExact; /** * 年对应的天干下标(国标,以正月初一为起点),0-9 */ private int yearGanIndex; /** * 年对应的地支下标(国标,以正月初一为起点),0-11 */ private int yearZhiIndex; /** * 年对应的天干下标(月干计算用,以立春为起点),0-9 */ private int yearGanIndexByLiChun; /** * 年对应的地支下标(月支计算用,以立春为起点),0-11 */ private int yearZhiIndexByLiChun; /** * 年对应的天干下标(最精确的,供八字用,以立春交接时刻为起点),0-9 */ private int yearGanIndexExact; /** * 年对应的地支下标(最精确的,供八字用,以立春交接时刻为起点),0-11 */ private int yearZhiIndexExact; /** * 周下标,0-6 */ private int weekIndex; /** * 阳历小时 */ private final int hour; /** * 阳历分钟 */ private final int minute; /** * 阳历秒钟 */ private final int second; /** * 八字 */ private EightChar eightChar; /** * 24节气表(对应阳历的准确时刻) */ private final Map jieQi = new LinkedHashMap(); /** * 默认使用当前日期初始化 */ public Lunar() { this(new Date()); } /** * 通过农历年月日初始化 * * @param lunarYear 年(农历) * @param lunarMonth 月(农历),1到12,闰月为负,即闰2月=-2 * @param lunarDay 日(农历),1到30 */ public Lunar(int lunarYear, int lunarMonth, int lunarDay) { this(lunarYear, lunarMonth, lunarDay, 0, 0, 0); } /** * 通过农历年月日时初始化 * * @param lunarYear 年(农历) * @param lunarMonth 月(农历),1到12,闰月为负,即闰2月=-2 * @param lunarDay 日(农历),1到30 * @param hour 小时(阳历) * @param minute 分钟(阳历) * @param second 秒钟(阳历) */ public Lunar(int lunarYear, int lunarMonth, int lunarDay, int hour, int minute, int second) { LunarYear y = LunarYear.fromYear(lunarYear); LunarMonth m = y.getMonth(lunarMonth); if (null == m) { throw new IllegalArgumentException(String.format("wrong lunar year %d month %d", lunarYear, lunarMonth)); } if (lunarDay < 1) { throw new IllegalArgumentException("lunar day must bigger than 0"); } int days = m.getDayCount(); if (lunarDay > days) { throw new IllegalArgumentException(String.format("only %d days in lunar year %d month %d", days, lunarYear, lunarMonth)); } this.year = lunarYear; this.month = lunarMonth; this.day = lunarDay; this.hour = hour; this.minute = minute; this.second = second; Solar noon = Solar.fromJulianDay(m.getFirstJulianDay() + lunarDay - 1); this.solar = Solar.fromYmdHms(noon.getYear(), noon.getMonth(), noon.getDay(), hour, minute, second); if (noon.getYear() != lunarYear) { y = LunarYear.fromYear(noon.getYear()); } compute(y); } /** * 通过阳历初始化 * * @param solar 阳历 */ public Lunar(Solar solar) { LunarYear ly = LunarYear.fromYear(solar.getYear()); for (LunarMonth m : ly.getMonths()) { int days = solar.subtract(Solar.fromJulianDay(m.getFirstJulianDay())); if (days < m.getDayCount()) { year = m.getYear(); month = m.getMonth(); day = days + 1; break; } } hour = solar.getHour(); minute = solar.getMinute(); second = solar.getSecond(); this.solar = solar; compute(ly); } /** * 通过阳历日期初始化 * * @param date 阳历日期 */ public Lunar(Date date) { this(Solar.fromDate(date)); } /** * 计算节气表 */ private void computeJieQi(LunarYear lunarYear) { List julianDays = lunarYear.getJieQiJulianDays(); for (int i = 0, j = JIE_QI_IN_USE.length; i < j; i++) { jieQi.put(JIE_QI_IN_USE[i], Solar.fromJulianDay(julianDays.get(i))); } } /** * 计算干支纪年 */ private void computeYear() { //以正月初一开始 int offset = year - 4; yearGanIndex = offset % 10; yearZhiIndex = offset % 12; if (yearGanIndex < 0) { yearGanIndex += 10; } if (yearZhiIndex < 0) { yearZhiIndex += 12; } //以立春作为新一年的开始的干支纪年 int g = yearGanIndex; int z = yearZhiIndex; //精确的干支纪年,以立春交接时刻为准 int gExact = yearGanIndex; int zExact = yearZhiIndex; int solarYear = solar.getYear(); String solarYmd = solar.toYmd(); String solarYmdHms = solar.toYmdHms(); //获取立春的阳历时刻 Solar liChun = jieQi.get("立春"); if (liChun.getYear() != solarYear) { liChun = jieQi.get("LI_CHUN"); } String liChunYmd = liChun.toYmd(); String liChunYmdHms = liChun.toYmdHms(); //阳历和阴历年份相同代表正月初一及以后 if (year == solarYear) { //立春日期判断 if (solarYmd.compareTo(liChunYmd) < 0) { g--; z--; } //立春交接时刻判断 if (solarYmdHms.compareTo(liChunYmdHms) < 0) { gExact--; zExact--; } } else if (year < solarYear) { if (solarYmd.compareTo(liChunYmd) >= 0) { g++; z++; } if (solarYmdHms.compareTo(liChunYmdHms) >= 0) { gExact++; zExact++; } } yearGanIndexByLiChun = (g < 0 ? g + 10 : g) % 10; yearZhiIndexByLiChun = (z < 0 ? z + 12 : z) % 12; yearGanIndexExact = (gExact < 0 ? gExact + 10 : gExact) % 10; yearZhiIndexExact = (zExact < 0 ? zExact + 12 : zExact) % 12; } /** * 计算干支纪月 */ private void computeMonth() { Solar start = null; Solar end; String ymd = solar.toYmd(); String time = solar.toYmdHms(); int size = JIE_QI_IN_USE.length; //序号:大雪以前-3,大雪到小寒之间-2,小寒到立春之间-1,立春之后0 int index = -3; for (int i = 0; i < size; i += 2) { end = jieQi.get(JIE_QI_IN_USE[i]); String symd = null == start ? ymd : start.toYmd(); if (ymd.compareTo(symd) >= 0 && ymd.compareTo(end.toYmd()) < 0) { break; } start = end; index++; } //干偏移值(以立春当天起算) int offset = (((yearGanIndexByLiChun + (index < 0 ? 1 : 0)) % 5 + 1) * 2) % 10; monthGanIndex = ((index < 0 ? index + 10 : index) + offset) % 10; monthZhiIndex = ((index < 0 ? index + 12 : index) + LunarUtil.BASE_MONTH_ZHI_INDEX) % 12; start = null; index = -3; for (int i = 0; i < size; i += 2) { end = jieQi.get(JIE_QI_IN_USE[i]); String stime = null == start ? time : start.toYmdHms(); if (time.compareTo(stime) >= 0 && time.compareTo(end.toYmdHms()) < 0) { break; } start = end; index++; } //干偏移值(以立春交接时刻起算) offset = (((yearGanIndexExact + (index < 0 ? 1 : 0)) % 5 + 1) * 2) % 10; monthGanIndexExact = ((index < 0 ? index + 10 : index) + offset) % 10; monthZhiIndexExact = ((index < 0 ? index + 12 : index) + LunarUtil.BASE_MONTH_ZHI_INDEX) % 12; } /** * 计算干支纪日 */ private void computeDay() { Solar noon = Solar.fromYmdHms(solar.getYear(), solar.getMonth(), solar.getDay(), 12, 0, 0); int offset = (int) noon.getJulianDay() - 11; dayGanIndex = offset % 10; dayZhiIndex = offset % 12; int dayGanExact = dayGanIndex; int dayZhiExact = dayZhiIndex; // 八字流派2,晚子时(夜子/子夜)日柱算当天 dayGanIndexExact2 = dayGanExact; dayZhiIndexExact2 = dayZhiExact; // 八字流派1,晚子时(夜子/子夜)日柱算明天 String hm = (hour < 10 ? "0" : "") + hour + ":" + (minute < 10 ? "0" : "") + minute; if (hm.compareTo("23:00") >= 0 && hm.compareTo("23:59") <= 0) { dayGanExact++; if (dayGanExact >= 10) { dayGanExact -= 10; } dayZhiExact++; if (dayZhiExact >= 12) { dayZhiExact -= 12; } } dayGanIndexExact = dayGanExact; dayZhiIndexExact = dayZhiExact; } /** * 计算干支纪时 */ private void computeTime() { String hm = (hour < 10 ? "0" : "") + hour + ":" + (minute < 10 ? "0" : "") + minute; timeZhiIndex = LunarUtil.getTimeZhiIndex(hm); timeGanIndex = (dayGanIndexExact % 5 * 2 + timeZhiIndex) % 10; } /** * 计算星期 */ private void computeWeek() { this.weekIndex = solar.getWeek(); } private void compute(LunarYear lunarYear) { computeJieQi(lunarYear); computeYear(); computeMonth(); computeDay(); computeTime(); computeWeek(); } /** * 通过指定阳历日期获取农历 * * @param date 阳历日期 * @return 农历 */ public static Lunar fromDate(Date date) { return new Lunar(date); } /** * 通过指定农历年月日获取农历 * * @param lunarYear 年(农历) * @param lunarMonth 月(农历),1到12,闰月为负,即闰2月=-2 * @param lunarDay 日(农历),1到31 * @return 农历 */ public static Lunar fromYmd(int lunarYear, int lunarMonth, int lunarDay) { return new Lunar(lunarYear, lunarMonth, lunarDay); } /** * 通过指定农历年月日获取农历 * * @param lunarYear 年(农历) * @param lunarMonth 月(农历),1到12,闰月为负,即闰2月=-2 * @param lunarDay 日(农历),1到31 * @param hour 小时(阳历) * @param minute 分钟(阳历) * @param second 秒钟(阳历) * @return 农历 */ public static Lunar fromYmdHms(int lunarYear, int lunarMonth, int lunarDay, int hour, int minute, int second) { return new Lunar(lunarYear, lunarMonth, lunarDay, hour, minute, second); } /** * 获取年份的天干(以正月初一作为新年的开始) * * @return 天干,如辛 * @deprecated 使用getYearGan */ @Deprecated public String getGan() { return getYearGan(); } /** * 获取年份的天干(以正月初一作为新年的开始) * * @return 天干,如辛 */ public String getYearGan() { return LunarUtil.GAN[yearGanIndex + 1]; } /** * 获取年份的天干(以立春当天作为新年的开始) * * @return 天干,如辛 */ public String getYearGanByLiChun() { return LunarUtil.GAN[yearGanIndexByLiChun + 1]; } /** * 获取最精确的年份天干(以立春交接的时刻作为新年的开始) * * @return 天干,如辛 */ public String getYearGanExact() { return LunarUtil.GAN[yearGanIndexExact + 1]; } /** * 获取年份的地支(以正月初一作为新年的开始) * * @return 地支,如亥 * @deprecated 使用getYearZhi */ @Deprecated public String getZhi() { return getYearZhi(); } /** * 获取年份的地支(以正月初一作为新年的开始) * * @return 地支,如亥 */ public String getYearZhi() { return LunarUtil.ZHI[yearZhiIndex + 1]; } /** * 获取年份的地支(以立春当天作为新年的开始) * * @return 地支,如亥 */ public String getYearZhiByLiChun() { return LunarUtil.ZHI[yearZhiIndexByLiChun + 1]; } /** * 获取最精确的年份地支(以立春交接的时刻作为新年的开始) * * @return 地支,如亥 */ public String getYearZhiExact() { return LunarUtil.ZHI[yearZhiIndexExact + 1]; } /** * 获取干支纪年(年柱)(以正月初一作为新年的开始) * * @return 年份的干支(年柱),如辛亥 */ public String getYearInGanZhi() { return getYearGan() + getYearZhi(); } /** * 获取干支纪年(年柱)(以立春当天作为新年的开始) * * @return 年份的干支(年柱),如辛亥 */ public String getYearInGanZhiByLiChun() { return getYearGanByLiChun() + getYearZhiByLiChun(); } /** * 获取干支纪年(年柱)(以立春交接的时刻作为新年的开始) * * @return 年份的干支(年柱),如辛亥 */ public String getYearInGanZhiExact() { return getYearGanExact() + getYearZhiExact(); } /** * 获取干支纪月(月柱)(以节交接当天起算) *

月天干口诀:甲己丙寅首,乙庚戊寅头。丙辛从庚寅,丁壬壬寅求,戊癸甲寅居,周而复始流。

*

月地支:正月起寅

* * @return 干支纪月(月柱),如己卯 */ public String getMonthInGanZhi() { return getMonthGan() + getMonthZhi(); } /** * 获取精确的干支纪月(月柱)(以节交接时刻起算) *

月天干口诀:甲己丙寅首,乙庚戊寅头。丙辛从庚寅,丁壬壬寅求,戊癸甲寅居,周而复始流。

*

月地支:正月起寅

* * @return 干支纪月(月柱),如己卯 */ public String getMonthInGanZhiExact() { return getMonthGanExact() + getMonthZhiExact(); } /** * 获取月天干(以节交接当天起算) * * @return 月天干,如己 */ public String getMonthGan() { return LunarUtil.GAN[monthGanIndex + 1]; } /** * 获取精确的月天干(以节交接时刻起算) * * @return 月天干,如己 */ public String getMonthGanExact() { return LunarUtil.GAN[monthGanIndexExact + 1]; } /** * 获取月地支(以节交接当天起算) * * @return 月地支,如卯 */ public String getMonthZhi() { return LunarUtil.ZHI[monthZhiIndex + 1]; } /** * 获取精确的月地支(以节交接时刻起算) * * @return 月地支,如卯 */ public String getMonthZhiExact() { return LunarUtil.ZHI[monthZhiIndexExact + 1]; } /** * 获取干支纪日(日柱) * * @return 干支纪日(日柱),如己卯 */ public String getDayInGanZhi() { return getDayGan() + getDayZhi(); } /** * 获取干支纪日(日柱,晚子时日柱算明天) * * @return 干支纪日(日柱),如己卯 */ public String getDayInGanZhiExact() { return getDayGanExact() + getDayZhiExact(); } /** * 获取干支纪日(日柱,晚子时日柱算当天) * * @return 干支纪日(日柱),如己卯 */ public String getDayInGanZhiExact2() { return getDayGanExact2() + getDayZhiExact2(); } /** * 获取日天干 * * @return 日天干,如甲 */ public String getDayGan() { return LunarUtil.GAN[dayGanIndex + 1]; } /** * 获取日天干(晚子时日柱算明天) * * @return 日天干,如甲 */ public String getDayGanExact() { return LunarUtil.GAN[dayGanIndexExact + 1]; } /** * 获取日天干(晚子时日柱算当天) * * @return 日天干,如甲 */ public String getDayGanExact2() { return LunarUtil.GAN[dayGanIndexExact2 + 1]; } /** * 获取日地支 * * @return 日地支,如卯 */ public String getDayZhi() { return LunarUtil.ZHI[dayZhiIndex + 1]; } /** * 获取日地支(晚子时日柱算明天) * * @return 日地支,如卯 */ public String getDayZhiExact() { return LunarUtil.ZHI[dayZhiIndexExact + 1]; } /** * 获取日地支(晚子时日柱算当天) * * @return 日地支,如卯 */ public String getDayZhiExact2() { return LunarUtil.ZHI[dayZhiIndexExact2 + 1]; } /** * 获取年生肖 * * @return 年生肖,如虎 * @deprecated 使用getYearShengXiao */ @Deprecated public String getShengxiao() { return getYearShengXiao(); } /** * 获取年生肖(以正月初一起算) * * @return 年生肖,如虎 */ public String getYearShengXiao() { return LunarUtil.SHENGXIAO[yearZhiIndex + 1]; } /** * 获取年生肖(以立春当天起算) * * @return 年生肖,如虎 */ public String getYearShengXiaoByLiChun() { return LunarUtil.SHENGXIAO[yearZhiIndexByLiChun + 1]; } /** * 获取精确的年生肖(以立春交接时刻起算) * * @return 年生肖,如虎 */ public String getYearShengXiaoExact() { return LunarUtil.SHENGXIAO[yearZhiIndexExact + 1]; } /** * 获取月生肖 * * @return 月生肖,如虎 */ public String getMonthShengXiao() { return LunarUtil.SHENGXIAO[monthZhiIndex + 1]; } /** * 获取日生肖 * * @return 日生肖,如虎 */ public String getDayShengXiao() { return LunarUtil.SHENGXIAO[dayZhiIndex + 1]; } /** * 获取时辰生肖 * * @return 时辰生肖,如虎 */ public String getTimeShengXiao() { return LunarUtil.SHENGXIAO[timeZhiIndex + 1]; } /** * 获取中文的年 * * @return 中文年,如二零零一 */ public String getYearInChinese() { String y = year + ""; StringBuilder s = new StringBuilder(); for (int i = 0, j = y.length(); i < j; i++) { s.append(LunarUtil.NUMBER[y.charAt(i) - '0']); } return s.toString(); } /** * 获取中文的月 * * @return 中文月,如正 */ public String getMonthInChinese() { return (month < 0 ? "闰" : "") + LunarUtil.MONTH[Math.abs(month)]; } /** * 获取中文日 * * @return 中文日,如初一 */ public String getDayInChinese() { return LunarUtil.DAY[day]; } /** * 获取时辰(地支) * * @return 时辰(地支) */ public String getTimeZhi() { return LunarUtil.ZHI[timeZhiIndex + 1]; } /** * 获取时辰(天干) * * @return 时辰(天干) */ public String getTimeGan() { return LunarUtil.GAN[timeGanIndex + 1]; } /** * 获取时辰干支(时柱),支持早子时和晚子时 * * @return 时辰干支(时柱) */ public String getTimeInGanZhi() { return getTimeGan() + getTimeZhi(); } /** * 获取季节 * * @return 农历季节 */ public String getSeason() { return LunarUtil.SEASON[Math.abs(month)]; } protected String convertJieQi(String name) { String jq = name; if ("DONG_ZHI".equals(jq)) { jq = "冬至"; } else if ("DA_HAN".equals(jq)) { jq = "大寒"; } else if ("XIAO_HAN".equals(jq)) { jq = "小寒"; } else if ("LI_CHUN".equals(jq)) { jq = "立春"; } else if ("DA_XUE".equals(jq)) { jq = "大雪"; } else if ("YU_SHUI".equals(jq)) { jq = "雨水"; } else if ("JING_ZHE".equals(jq)) { jq = "惊蛰"; } return jq; } /** * 获取节令 * * @return 节令 */ public String getJie() { for (int i = 0, j = JIE_QI_IN_USE.length; i < j; i += 2) { String key = JIE_QI_IN_USE[i]; Solar d = jieQi.get(key); if (d.getYear() == solar.getYear() && d.getMonth() == solar.getMonth() && d.getDay() == solar.getDay()) { return convertJieQi(key); } } return ""; } /** * 获取气令 * * @return 气令 */ public String getQi() { for (int i = 1, j = JIE_QI_IN_USE.length; i < j; i += 2) { String key = JIE_QI_IN_USE[i]; Solar d = jieQi.get(key); if (d.getYear() == solar.getYear() && d.getMonth() == solar.getMonth() && d.getDay() == solar.getDay()) { return convertJieQi(key); } } return ""; } /** * 获取星期,0代表周日,1代表周一 * * @return 0123456 */ public int getWeek() { return weekIndex; } /** * 获取星期的中文 * * @return 日一二三四五六 */ public String getWeekInChinese() { return SolarUtil.WEEK[getWeek()]; } /** * 获取宿 * * @return 宿 */ public String getXiu() { return LunarUtil.XIU.get(getDayZhi() + getWeek()); } /** * 获取宿吉凶 * * @return 吉/凶 */ public String getXiuLuck() { return LunarUtil.XIU_LUCK.get(getXiu()); } /** * 获取宿歌诀 * * @return 宿歌诀 */ public String getXiuSong() { return LunarUtil.XIU_SONG.get(getXiu()); } /** * 获取政 * * @return 政 */ public String getZheng() { return LunarUtil.ZHENG.get(getXiu()); } /** * 获取动物 * * @return 动物 */ public String getAnimal() { return LunarUtil.ANIMAL.get(getXiu()); } /** * 获取宫 * * @return 宫 */ public String getGong() { return LunarUtil.GONG.get(getXiu()); } /** * 获取兽 * * @return 兽 */ public String getShou() { return LunarUtil.SHOU.get(getGong()); } /** * 获取节日,有可能一天会有多个节日 * * @return 节日列表,如春节 */ public List getFestivals() { List l = new ArrayList(); String f = LunarUtil.FESTIVAL.get(month + "-" + day); if (null != f) { l.add(f); } if (Math.abs(month) == 12 && day >= 29 && year != next(1).getYear()) { l.add("除夕"); } return l; } /** * 获取非正式的节日,有可能一天会有多个节日 * * @return 非正式的节日列表,如中元节 */ public List getOtherFestivals() { List l = new ArrayList(); List fs = LunarUtil.OTHER_FESTIVAL.get(month + "-" + day); if (null != fs) { l.addAll(fs); } String solarYmd = solar.toYmd(); if (solarYmd.equals(jieQi.get("清明").next(-1).toYmd())) { l.add("寒食节"); } Solar jq = jieQi.get("立春"); int offset = 4 - jq.getLunar().getDayGanIndex(); if (offset < 0) { offset += 10; } if (solarYmd.equals(jq.next(offset + 40).toYmd())) { l.add("春社"); } jq = jieQi.get("立秋"); offset = 4 - jq.getLunar().getDayGanIndex(); if (offset < 0) { offset += 10; } if (solarYmd.equals(jq.next(offset + 40).toYmd())) { l.add("秋社"); } return l; } /** * 获取彭祖百忌天干 * * @return 彭祖百忌天干 */ public String getPengZuGan() { return LunarUtil.PENGZU_GAN[dayGanIndex + 1]; } /** * 获取彭祖百忌地支 * * @return 彭祖百忌地支 */ public String getPengZuZhi() { return LunarUtil.PENGZU_ZHI[dayZhiIndex + 1]; } /** * 获取日喜神方位 * * @return 方位,如艮 * @deprecated 使用getDayPositionXi */ public String getPositionXi() { return getDayPositionXi(); } /** * 获取喜神方位描述 * * @return 方位描述,如东北 * @deprecated 使用getDayPositionXiDesc */ public String getPositionXiDesc() { return getDayPositionXiDesc(); } /** * 获取阳贵神方位 * * @return 阳贵神方位,如艮 * @deprecated 使用getDayPositionYangGui */ public String getPositionYangGui() { return getDayPositionYangGui(); } /** * 获取阳贵神方位描述 * * @return 方位描述,如东北 * @deprecated 使用getDayPositionYangGuiDesc */ public String getPositionYangGuiDesc() { return getDayPositionYangGuiDesc(); } /** * 获取阴贵神方位 * * @return 方位,如艮 * @deprecated 使用getDayPositionYinGui */ public String getPositionYinGui() { return getDayPositionYinGui(); } /** * 获取阴贵神方位描述 * * @return 阴贵神方位描述,如东北 * @deprecated 使用getDayPositionYinGuiDesc */ public String getPositionYinGuiDesc() { return getDayPositionYinGuiDesc(); } /** * 获取福神方位 * * @return 方位,如艮 * @deprecated 使用getDayPositionFu */ public String getPositionFu() { return getDayPositionFu(); } /** * 获取福神方位描述 * * @return 方位描述,如东北 * @deprecated 使用getDayPositionFuDesc */ public String getPositionFuDesc() { return getDayPositionFuDesc(); } /** * 获取财神方位 * * @return 方位,如艮 * @deprecated 使用getDayPositionCai */ public String getPositionCai() { return getDayPositionCai(); } /** * 获取财神方位描述 * * @return 方位描述,如东北 * @deprecated 使用getDayPositionCaiDesc */ public String getPositionCaiDesc() { return getDayPositionCaiDesc(); } /** * 获取日喜神方位 * * @return 方位,如艮 */ public String getDayPositionXi() { return LunarUtil.POSITION_XI[dayGanIndex + 1]; } /** * 获取日喜神方位描述 * * @return 方位描述,如东北 */ public String getDayPositionXiDesc() { return LunarUtil.POSITION_DESC.get(getDayPositionXi()); } /** * 获取日阳贵神方位 * * @return 方位,如艮 */ public String getDayPositionYangGui() { return LunarUtil.POSITION_YANG_GUI[dayGanIndex + 1]; } /** * 获取日阳贵神方位描述 * * @return 方位描述,如东北 */ public String getDayPositionYangGuiDesc() { return LunarUtil.POSITION_DESC.get(getDayPositionYangGui()); } /** * 获取日阴贵神方位 * * @return 阴贵神方位,如艮 */ public String getDayPositionYinGui() { return LunarUtil.POSITION_YIN_GUI[dayGanIndex + 1]; } /** * 获取日阴贵神方位描述 * * @return 方位描述,如东北 */ public String getDayPositionYinGuiDesc() { return LunarUtil.POSITION_DESC.get(getDayPositionYinGui()); } /** * 获取日福神方位(默认流派:2) * * @return 福神方位,如艮 */ public String getDayPositionFu() { return getDayPositionFu(2); } /** * 获取日福神方位 * * @param sect 流派,1或2 * @return 方位,如艮 */ public String getDayPositionFu(int sect) { return (1 == sect ? LunarUtil.POSITION_FU : LunarUtil.POSITION_FU_2)[dayGanIndex + 1]; } /** * 获取日福神方位描述(默认流派:2) * * @return 方位描述,如东北 */ public String getDayPositionFuDesc() { return getDayPositionFuDesc(2); } /** * 获取日福神方位描述 * * @param sect 流派,1或2 * @return 方位描述,如东北 */ public String getDayPositionFuDesc(int sect) { return LunarUtil.POSITION_DESC.get(getDayPositionFu(sect)); } /** * 获取日财神方位 * * @return 方位,如艮 */ public String getDayPositionCai() { return LunarUtil.POSITION_CAI[dayGanIndex + 1]; } /** * 获取日财神方位描述 * * @return 方位描述,如东北 */ public String getDayPositionCaiDesc() { return LunarUtil.POSITION_DESC.get(getDayPositionCai()); } /** * 获取年太岁方位(默认流派2新年以立春零点起算) * * @return 方位,如艮 */ public String getYearPositionTaiSui() { return getYearPositionTaiSui(2); } /** * 获取年太岁方位 * * @param sect 流派:2为新年以立春零点起算;1为新年以正月初一起算;3为新年以立春节气交接的时刻起算 * @return 方位,如艮 */ public String getYearPositionTaiSui(int sect) { int yearZhiIndex; switch (sect) { case 1: yearZhiIndex = this.yearZhiIndex; break; case 3: yearZhiIndex = this.yearZhiIndexExact; break; default: yearZhiIndex = this.yearZhiIndexByLiChun; } return LunarUtil.POSITION_TAI_SUI_YEAR[yearZhiIndex]; } /** * 获取年太岁方位描述(默认流派2新年以立春零点起算) * * @return 方位描述,如东北 */ public String getYearPositionTaiSuiDesc() { return getYearPositionTaiSuiDesc(2); } /** * 获取年太岁方位描述 * * @param sect 流派:2为新年以立春零点起算;1为新年以正月初一起算;3为新年以立春节气交接的时刻起算 * @return 方位描述,如东北 */ public String getYearPositionTaiSuiDesc(int sect) { return LunarUtil.POSITION_DESC.get(getYearPositionTaiSui(sect)); } protected String getMonthPositionTaiSui(int monthZhiIndex, int monthGanIndex) { String p; int m = monthZhiIndex - LunarUtil.BASE_MONTH_ZHI_INDEX; if (m < 0) { m += 12; } m = m % 4; switch (m) { case 0: p = "艮"; break; case 2: p = "坤"; break; case 3: p = "巽"; break; default: p = LunarUtil.POSITION_GAN[monthGanIndex]; } return p; } /** * 获取月太岁方位(默认流派2新的一月以节交接当天零点起算) * * @return 太岁方位,如艮 */ public String getMonthPositionTaiSui() { return getMonthPositionTaiSui(2); } /** * 获取月太岁方位 * * @param sect 流派:2为新的一月以节交接当天零点起算;3为新的一月以节交接准确时刻起算 * @return 太岁方位,如艮 */ public String getMonthPositionTaiSui(int sect) { int monthZhiIndex; int monthGanIndex; if (sect == 3) { monthZhiIndex = this.monthZhiIndexExact; monthGanIndex = this.monthGanIndexExact; } else { monthZhiIndex = this.monthZhiIndex; monthGanIndex = this.monthGanIndex; } return getMonthPositionTaiSui(monthZhiIndex, monthGanIndex); } /** * 获取月太岁方位描述(默认流派2新的一月以节交接当天零点起算) * * @return 太岁方位描述,如东北 */ public String getMonthPositionTaiSuiDesc() { return getMonthPositionTaiSuiDesc(2); } /** * 获取月太岁方位描述 * * @param sect 流派:2为新的一月以节交接当天零点起算;3为新的一月以节交接准确时刻起算 * @return 太岁方位描述,如东北 */ public String getMonthPositionTaiSuiDesc(int sect) { return LunarUtil.POSITION_DESC.get(getMonthPositionTaiSui(sect)); } protected String getDayPositionTaiSui(String dayInGanZhi, int yearZhiIndex) { String p; if ("甲子,乙丑,丙寅,丁卯,戊辰,已巳".contains(dayInGanZhi)) { p = "震"; } else if ("丙子,丁丑,戊寅,已卯,庚辰,辛巳".contains(dayInGanZhi)) { p = "离"; } else if ("戊子,已丑,庚寅,辛卯,壬辰,癸巳".contains(dayInGanZhi)) { p = "中"; } else if ("庚子,辛丑,壬寅,癸卯,甲辰,乙巳".contains(dayInGanZhi)) { p = "兑"; } else if ("壬子,癸丑,甲寅,乙卯,丙辰,丁巳".contains(dayInGanZhi)) { p = "坎"; } else { p = LunarUtil.POSITION_TAI_SUI_YEAR[yearZhiIndex]; } return p; } /** * 获取日太岁方位(默认流派2新年以立春零点起算) * * @return 太岁方位,如艮 */ public String getDayPositionTaiSui() { return getDayPositionTaiSui(2); } /** * 获取日太岁方位 * * @param sect 流派:2新年以立春零点起算;1新年以正月初一起算;3新年以立春节气交接的时刻起算 * @return 太岁方位,如艮 */ public String getDayPositionTaiSui(int sect) { String dayInGanZhi; int yearZhiIndex; switch (sect) { case 1: dayInGanZhi = getDayInGanZhi(); yearZhiIndex = this.yearZhiIndex; break; case 3: dayInGanZhi = getDayInGanZhi(); yearZhiIndex = this.yearZhiIndexExact; break; default: dayInGanZhi = getDayInGanZhiExact2(); yearZhiIndex = this.yearZhiIndexByLiChun; } return getDayPositionTaiSui(dayInGanZhi, yearZhiIndex); } /** * 获取日太岁方位描述(默认流派2新年以立春零点起算) * * @return 太岁方位描述,如东北 */ public String getDayPositionTaiSuiDesc() { return getDayPositionTaiSuiDesc(2); } /** * 获取日太岁方位描述 * * @param sect 流派:2新年以立春零点起算;1新年以正月初一起算;3新年以立春节气交接的时刻起算 * @return 太岁方位描述,如东北 */ public String getDayPositionTaiSuiDesc(int sect) { return LunarUtil.POSITION_DESC.get(getDayPositionTaiSui(sect)); } /** * 获取时辰喜神方位 * * @return 喜神方位,如艮 */ public String getTimePositionXi() { return LunarUtil.POSITION_XI[timeGanIndex + 1]; } /** * 获取时辰喜神方位描述 * * @return 喜神方位描述,如东北 */ public String getTimePositionXiDesc() { return LunarUtil.POSITION_DESC.get(getTimePositionXi()); } /** * 获取时辰阳贵神方位 * * @return 阳贵神方位,如艮 */ public String getTimePositionYangGui() { return LunarUtil.POSITION_YANG_GUI[timeGanIndex + 1]; } /** * 获取时辰阳贵神方位描述 * * @return 阳贵神方位描述,如东北 */ public String getTimePositionYangGuiDesc() { return LunarUtil.POSITION_DESC.get(getTimePositionYangGui()); } /** * 获取时辰阴贵神方位 * * @return 阴贵神方位,如艮 */ public String getTimePositionYinGui() { return LunarUtil.POSITION_YIN_GUI[timeGanIndex + 1]; } /** * 获取时辰阴贵神方位描述 * * @return 阴贵神方位描述,如东北 */ public String getTimePositionYinGuiDesc() { return LunarUtil.POSITION_DESC.get(getTimePositionYinGui()); } /** * 获取时辰福神方位,默认流派2 * * @return 福神方位,如艮 */ public String getTimePositionFu() { return getTimePositionFu(2); } /** * 获取时辰福神方位 * * @param sect 流派,1或2 * @return 福神方位,如艮 */ public String getTimePositionFu(int sect) { return (1 == sect ? LunarUtil.POSITION_FU : LunarUtil.POSITION_FU_2)[timeGanIndex + 1]; } /** * 获取时辰福神方位描述,默认流派2 * * @return 福神方位描述,如东北 */ public String getTimePositionFuDesc() { return getTimePositionFuDesc(2); } /** * 获取时辰福神方位描述 * * @param sect 流派,1或2 * @return 福神方位描述,如东北 */ public String getTimePositionFuDesc(int sect) { return LunarUtil.POSITION_DESC.get(getTimePositionFu(sect)); } /** * 获取时辰财神方位 * * @return 财神方位,如艮 */ public String getTimePositionCai() { return LunarUtil.POSITION_CAI[timeGanIndex + 1]; } /** * 获取时辰财神方位描述 * * @return 财神方位描述,如东北 */ public String getTimePositionCaiDesc() { return LunarUtil.POSITION_DESC.get(getTimePositionCai()); } /** * 获取冲 * * @return 冲,如申 * @deprecated 使用getDayChong */ @Deprecated public String getChong() { return getDayChong(); } /** * 获取无情之克的冲天干 * * @return 无情之克的冲天干,如甲 * @deprecated 使用getDayChongGan */ @Deprecated public String getChongGan() { return getDayChongGan(); } /** * 获取有情之克的冲天干 * * @return 有情之克的冲天干,如甲 * @deprecated 使用getDayChongGanTie */ @Deprecated public String getChongGanTie() { return getDayChongGanTie(); } /** * 获取冲生肖 * * @return 冲生肖,如猴 * @deprecated 使用getDayChongShengXiao */ @Deprecated public String getChongShengXiao() { return getDayChongShengXiao(); } /** * 获取冲描述 * * @return 冲描述,如(壬申)猴 * @deprecated 使用getDayChongDesc */ @Deprecated public String getChongDesc() { return getDayChongDesc(); } /** * 获取煞 * * @return 煞,如北 * @deprecated 使用getDaySha */ @Deprecated public String getSha() { return getDaySha(); } /** * 获取年纳音 * * @return 年纳音,如剑锋金 */ public String getYearNaYin() { return LunarUtil.NAYIN.get(getYearInGanZhi()); } /** * 获取月纳音 * * @return 月纳音,如剑锋金 */ public String getMonthNaYin() { return LunarUtil.NAYIN.get(getMonthInGanZhi()); } /** * 获取日纳音 * * @return 日纳音,如剑锋金 */ public String getDayNaYin() { return LunarUtil.NAYIN.get(getDayInGanZhi()); } /** * 获取时辰纳音 * * @return 时辰纳音,如剑锋金 */ public String getTimeNaYin() { return LunarUtil.NAYIN.get(getTimeInGanZhi()); } /** * 获取八字,男性也称乾造,女性也称坤造(以立春交接时刻作为新年的开始) * * @return 八字(男性也称乾造,女性也称坤造) * @deprecated 使用getEightChar */ @Deprecated public List getBaZi() { List l = new ArrayList(4); EightChar eightChar = getEightChar(); l.add(eightChar.getYear()); l.add(eightChar.getMonth()); l.add(eightChar.getDay()); l.add(eightChar.getTime()); return l; } /** * 获取八字五行 * * @return 八字五行 * @deprecated 使用getEightChar */ @Deprecated public List getBaZiWuXing() { List l = new ArrayList(4); EightChar eightChar = getEightChar(); l.add(eightChar.getYearWuXing()); l.add(eightChar.getMonthWuXing()); l.add(eightChar.getDayWuXing()); l.add(eightChar.getTimeWuXing()); return l; } /** * 获取八字纳音 * * @return 八字纳音 * @deprecated 使用getEightChar */ @Deprecated public List getBaZiNaYin() { List l = new ArrayList(4); EightChar eightChar = getEightChar(); l.add(eightChar.getYearNaYin()); l.add(eightChar.getMonthNaYin()); l.add(eightChar.getDayNaYin()); l.add(eightChar.getTimeNaYin()); return l; } /** * 获取八字天干十神,日柱十神为日主,其余三柱根据天干十神表查询 * * @return 八字天干十神 * @deprecated 使用getEightChar */ @Deprecated public List getBaZiShiShenGan() { List l = new ArrayList(4); EightChar eightChar = getEightChar(); l.add(eightChar.getYearShiShenGan()); l.add(eightChar.getMonthShiShenGan()); l.add(eightChar.getDayShiShenGan()); l.add(eightChar.getTimeShiShenGan()); return l; } /** * 获取八字地支十神,根据地支十神表查询 * * @return 八字地支十神 * @deprecated 使用getEightChar */ @Deprecated public List getBaZiShiShenZhi() { List l = new ArrayList(4); EightChar eightChar = getEightChar(); l.add(eightChar.getYearShiShenZhi().get(0)); l.add(eightChar.getMonthShiShenZhi().get(0)); l.add(eightChar.getDayShiShenZhi().get(0)); l.add(eightChar.getTimeShiShenZhi().get(0)); return l; } /** * 获取八字年支十神 * * @return 八字年支十神 * @deprecated 使用getEightChar */ @Deprecated public List getBaZiShiShenYearZhi() { return getEightChar().getYearShiShenZhi(); } /** * 获取八字月支十神 * * @return 八字月支十神 * @deprecated 使用getEightChar */ @Deprecated public List getBaZiShiShenMonthZhi() { return getEightChar().getMonthShiShenZhi(); } /** * 获取八字日支十神 * * @return 八字日支十神 * @deprecated 使用getEightChar */ @Deprecated public List getBaZiShiShenDayZhi() { return getEightChar().getDayShiShenZhi(); } /** * 获取八字时支十神 * * @return 八字时支十神 * @deprecated 使用getEightChar */ @Deprecated public List getBaZiShiShenTimeZhi() { return getEightChar().getTimeShiShenZhi(); } /** * 获取十二执星:建、除、满、平、定、执、破、危、成、收、开、闭。当月支与日支相同即为建,依次类推 * * @return 执星 */ public String getZhiXing() { int offset = dayZhiIndex - monthZhiIndex; if (offset < 0) { offset += 12; } return LunarUtil.ZHI_XING[offset + 1]; } /** * 获取值日天神 * * @return 值日天神 */ public String getDayTianShen() { return LunarUtil.TIAN_SHEN[(dayZhiIndex + LunarUtil.ZHI_TIAN_SHEN_OFFSET.get(getMonthZhi())) % 12 + 1]; } /** * 获取值时天神 * * @return 值时天神 */ public String getTimeTianShen() { return LunarUtil.TIAN_SHEN[(timeZhiIndex + LunarUtil.ZHI_TIAN_SHEN_OFFSET.get(getDayZhiExact())) % 12 + 1]; } /** * 获取值日天神类型:黄道/黑道 * * @return 值日天神类型:黄道/黑道 */ public String getDayTianShenType() { return LunarUtil.TIAN_SHEN_TYPE.get(getDayTianShen()); } /** * 获取值时天神类型:黄道/黑道 * * @return 值时天神类型:黄道/黑道 */ public String getTimeTianShenType() { return LunarUtil.TIAN_SHEN_TYPE.get(getTimeTianShen()); } /** * 获取值日天神吉凶 * * @return 吉/凶 */ public String getDayTianShenLuck() { return LunarUtil.TIAN_SHEN_TYPE_LUCK.get(getDayTianShenType()); } /** * 获取值时天神吉凶 * * @return 吉/凶 */ public String getTimeTianShenLuck() { return LunarUtil.TIAN_SHEN_TYPE_LUCK.get(getTimeTianShenType()); } /** * 获取逐日胎神方位 * * @return 逐日胎神方位 */ public String getDayPositionTai() { return LunarUtil.POSITION_TAI_DAY[LunarUtil.getJiaZiIndex(getDayInGanZhi())]; } /** * 获取逐月胎神方位,闰月无 * * @return 逐月胎神方位 */ public String getMonthPositionTai() { if (month < 0) { return ""; } return LunarUtil.POSITION_TAI_MONTH[month - 1]; } /** * 使用默认流派1(以节交接当天起算月)获取每日宜,如果没有,返回["无"] * * @return 宜 */ public List getDayYi() { return getDayYi(1); } /** * 获取每日宜,如果没有,返回["无"] * * @param sect 流派,1以节交接当天起算月,2以节交接时刻起算月 * @return 宜 */ public List getDayYi(int sect) { return LunarUtil.getDayYi(2 == sect ? getMonthInGanZhiExact() : getMonthInGanZhi(), getDayInGanZhi()); } /** * 使用默认流派1(以节交接当天起算月)获取每日忌,如果没有,返回["无"] * * @return 忌 */ public List getDayJi() { return getDayJi(1); } /** * 获取每日忌,如果没有,返回["无"] * * @param sect 流派,1以节交接当天起算月,2以节交接时刻起算月 * @return 忌 */ public List getDayJi(int sect) { return LunarUtil.getDayJi(2 == sect ? getMonthInGanZhiExact() : getMonthInGanZhi(), getDayInGanZhi()); } /** * 获取日吉神(宜趋),如果没有,返回["无"] * * @return 日吉神 */ public List getDayJiShen() { return LunarUtil.getDayJiShen(getMonth(), getDayInGanZhi()); } /** * 获取日凶煞(宜忌),如果没有,返回["无"] * * @return 日凶煞 */ public List getDayXiongSha() { return LunarUtil.getDayXiongSha(getMonth(), getDayInGanZhi()); } /** * 获取日冲 * * @return 日冲,如申 */ public String getDayChong() { return LunarUtil.CHONG[dayZhiIndex]; } /** * 获取日煞 * * @return 日煞,如北 */ public String getDaySha() { return LunarUtil.SHA.get(getDayZhi()); } /** * 获取日冲描述 * * @return 日冲描述,如(壬申)猴 */ public String getDayChongDesc() { return "(" + getDayChongGan() + getDayChong() + ")" + getDayChongShengXiao(); } /** * 获取日冲生肖 * * @return 日冲生肖,如猴 */ public String getDayChongShengXiao() { String chong = getDayChong(); for (int i = 0, j = LunarUtil.ZHI.length; i < j; i++) { if (LunarUtil.ZHI[i].equals(chong)) { return LunarUtil.SHENGXIAO[i]; } } return ""; } /** * 获取无情之克的日冲天干 * * @return 无情之克的日冲天干,如甲 */ public String getDayChongGan() { return LunarUtil.CHONG_GAN[dayGanIndex]; } /** * 获取有情之克的日冲天干 * * @return 有情之克的日冲天干,如甲 */ public String getDayChongGanTie() { return LunarUtil.CHONG_GAN_TIE[dayGanIndex]; } /** * 获取时冲 * * @return 时冲,如申 */ public String getTimeChong() { return LunarUtil.CHONG[timeZhiIndex]; } /** * 获取时煞 * * @return 时煞,如北 */ public String getTimeSha() { return LunarUtil.SHA.get(getTimeZhi()); } /** * 获取时冲生肖 * * @return 时冲生肖,如猴 */ public String getTimeChongShengXiao() { String chong = getTimeChong(); for (int i = 0, j = LunarUtil.ZHI.length; i < j; i++) { if (LunarUtil.ZHI[i].equals(chong)) { return LunarUtil.SHENGXIAO[i]; } } return ""; } /** * 获取时冲描述 * * @return 时冲描述,如(壬申)猴 */ public String getTimeChongDesc() { return "(" + getTimeChongGan() + getTimeChong() + ")" + getTimeChongShengXiao(); } /** * 获取无情之克的时冲天干 * * @return 无情之克的时冲天干,如甲 */ public String getTimeChongGan() { return LunarUtil.CHONG_GAN[timeGanIndex]; } /** * 获取有情之克的时冲天干 * * @return 有情之克的时冲天干,如甲 */ public String getTimeChongGanTie() { return LunarUtil.CHONG_GAN_TIE[timeGanIndex]; } /** * 获取时辰宜,如果没有,返回["无"] * * @return 宜 */ public List getTimeYi() { return LunarUtil.getTimeYi(getDayInGanZhiExact(), getTimeInGanZhi()); } /** * 获取时辰忌,如果没有,返回["无"] * * @return 忌 */ public List getTimeJi() { return LunarUtil.getTimeJi(getDayInGanZhiExact(), getTimeInGanZhi()); } /** * 获取月相 * * @return 月相 */ public String getYueXiang() { return LunarUtil.YUE_XIANG[day]; } protected NineStar getYearNineStar(String yearInGanZhi) { int indexExact = LunarUtil.getJiaZiIndex(yearInGanZhi) + 1; int index = LunarUtil.getJiaZiIndex(this.getYearInGanZhi()) + 1; int yearOffset = indexExact - index; if (yearOffset > 1) { yearOffset -= 60; } else if (yearOffset < -1) { yearOffset += 60; } int yuan = ((this.year + yearOffset + 2696) / 60) % 3; int offset = (62 + yuan * 3 - indexExact) % 9; if (0 == offset) { offset = 9; } return NineStar.fromIndex(offset - 1); } /** * 获取值年九星(默认流派2新年以立春零点起算。流年紫白星起例歌诀:年上吉星论甲子,逐年星逆中宫起;上中下作三元汇,一上四中七下兑。) * * @return 九星 */ public NineStar getYearNineStar() { return getYearNineStar(2); } /** * 获取值年九星(流年紫白星起例歌诀:年上吉星论甲子,逐年星逆中宫起;上中下作三元汇,一上四中七下兑。) * * @param sect 流派:2为新年以立春零点起算;1为新年以正月初一起算;3为新年以立春节气交接的时刻起算 * @return 九星 */ public NineStar getYearNineStar(int sect) { String yearInGanZhi; switch (sect) { case 1: yearInGanZhi = this.getYearInGanZhi(); break; case 3: yearInGanZhi = this.getYearInGanZhiExact(); break; default: yearInGanZhi = this.getYearInGanZhiByLiChun(); } return getYearNineStar(yearInGanZhi); } protected NineStar getMonthNineStar(int yearZhiIndex, int monthZhiIndex) { int index = yearZhiIndex % 3; int n = 27 - index * 3; if (monthZhiIndex < LunarUtil.BASE_MONTH_ZHI_INDEX) { n -= 3; } int offset = (n - monthZhiIndex) % 9; return NineStar.fromIndex(offset); } /** * 获取值月九星(流派2新的一月以节交接当天零点起算。月紫白星歌诀:子午卯酉八白起,寅申巳亥二黑求,辰戌丑未五黄中。) * * @return 九星 */ public NineStar getMonthNineStar() { return getMonthNineStar(2); } /** * 获取值月九星(月紫白星歌诀:子午卯酉八白起,寅申巳亥二黑求,辰戌丑未五黄中。) * * @param sect 流派:2为新的一月以节交接当天零点起算;3为新的一月以节交接准确时刻起算 * @return 九星 */ public NineStar getMonthNineStar(int sect) { int yearZhiIndex; int monthZhiIndex; switch (sect) { case 1: yearZhiIndex = this.yearZhiIndex; monthZhiIndex = this.monthZhiIndex; break; case 3: yearZhiIndex = this.yearZhiIndexExact; monthZhiIndex = this.monthZhiIndexExact; break; default: yearZhiIndex = this.yearZhiIndexByLiChun; monthZhiIndex = this.monthZhiIndex; } return getMonthNineStar(yearZhiIndex, monthZhiIndex); } /** * 获取值日九星(日家紫白星歌诀:日家白法不难求,二十四气六宫周;冬至雨水及谷雨,阳顺一七四中游;夏至处暑霜降后,九三六星逆行求。) * * @return 九星 */ public NineStar getDayNineStar() { String solarYmd = solar.toYmd(); Solar dongZhi = jieQi.get("冬至"); Solar dongZhi2 = jieQi.get("DONG_ZHI"); Solar xiaZhi = jieQi.get("夏至"); int dongZhiIndex = LunarUtil.getJiaZiIndex(dongZhi.getLunar().getDayInGanZhi()); int dongZhiIndex2 = LunarUtil.getJiaZiIndex(dongZhi2.getLunar().getDayInGanZhi()); int xiaZhiIndex = LunarUtil.getJiaZiIndex(xiaZhi.getLunar().getDayInGanZhi()); Solar solarShunBai; Solar solarShunBai2; Solar solarNiZi; if (dongZhiIndex > 29) { solarShunBai = dongZhi.next(60 - dongZhiIndex); } else { solarShunBai = dongZhi.next(-dongZhiIndex); } String solarShunBaiYmd = solarShunBai.toYmd(); if (dongZhiIndex2 > 29) { solarShunBai2 = dongZhi2.next(60 - dongZhiIndex2); } else { solarShunBai2 = dongZhi2.next(-dongZhiIndex2); } String solarShunBaiYmd2 = solarShunBai2.toYmd(); if (xiaZhiIndex > 29) { solarNiZi = xiaZhi.next(60 - xiaZhiIndex); } else { solarNiZi = xiaZhi.next(-xiaZhiIndex); } String solarNiZiYmd = solarNiZi.toYmd(); int offset = 0; if (solarYmd.compareTo(solarShunBaiYmd) >= 0 && solarYmd.compareTo(solarNiZiYmd) < 0) { offset = solar.subtract(solarShunBai) % 9; } else if (solarYmd.compareTo(solarNiZiYmd) >= 0 && solarYmd.compareTo(solarShunBaiYmd2) < 0) { offset = 8 - (solar.subtract(solarNiZi) % 9); } else if (solarYmd.compareTo(solarShunBaiYmd2) >= 0) { offset = solar.subtract(solarShunBai2) % 9; } else if (solarYmd.compareTo(solarShunBaiYmd) < 0) { offset = (8 + solarShunBai.subtract(solar)) % 9; } return NineStar.fromIndex(offset); } /** * 获取值时九星(时家紫白星歌诀:三元时白最为佳,冬至阳生顺莫差,孟日七宫仲一白,季日四绿发萌芽,每把时辰起甲子,本时星耀照光华,时星移入中宫去,顺飞八方逐细查。夏至阴生逆回首,孟归三碧季加六,仲在九宫时起甲,依然掌中逆轮跨。) * * @return 九星 */ public NineStar getTimeNineStar() { String solarYmd = solar.toYmd(); boolean asc = false; if ((solarYmd.compareTo(jieQi.get("冬至").toYmd()) >= 0 && solarYmd.compareTo(jieQi.get("夏至").toYmd()) < 0)) { asc = true; } else if (solarYmd.compareTo(jieQi.get("DONG_ZHI").toYmd()) >= 0) { asc = true; } int start = asc ? 6 : 2; String dayZhi = getDayZhi(); if ("子午卯酉".contains(dayZhi)) { start = asc ? 0 : 8; } else if ("辰戌丑未".contains(dayZhi)) { start = asc ? 3 : 5; } int index = asc ? start + timeZhiIndex : start + 9 - timeZhiIndex; return new NineStar(index % 9); } /** * 获取节气表(节气名称:阳历),节气交接时刻精确到秒,以冬至开头,按先后顺序排列 * * @return 节气表 */ public Map getJieQiTable() { return jieQi; } /** * 获取下一节令(顺推的第一个节令) * * @return 节气 */ public JieQi getNextJie() { return getNextJie(false); } /** * 获取下一节令(顺推的第一个节令) * * @param wholeDay 是否按天计 * @return 节气 */ public JieQi getNextJie(boolean wholeDay) { int l = JIE_QI_IN_USE.length / 2; String[] conditions = new String[l]; for (int i = 0; i < l; i++) { conditions[i] = JIE_QI_IN_USE[i * 2]; } return getNearJieQi(true, conditions, wholeDay); } /** * 获取上一节令(逆推的第一个节令) * * @return 节气 */ public JieQi getPrevJie() { return getPrevJie(false); } /** * 获取上一节令(逆推的第一个节令) * * @param wholeDay 是否按天计 * @return 节气 */ public JieQi getPrevJie(boolean wholeDay) { int l = JIE_QI_IN_USE.length / 2; String[] conditions = new String[l]; for (int i = 0; i < l; i++) { conditions[i] = JIE_QI_IN_USE[i * 2]; } return getNearJieQi(false, conditions, wholeDay); } /** * 获取下一气令(顺推的第一个气令) * * @return 节气 */ public JieQi getNextQi() { return getNextQi(false); } /** * 获取下一气令(顺推的第一个气令) * * @param wholeDay 是否按天计 * @return 节气 */ public JieQi getNextQi(boolean wholeDay) { int l = JIE_QI_IN_USE.length / 2; String[] conditions = new String[l]; for (int i = 0; i < l; i++) { conditions[i] = JIE_QI_IN_USE[i * 2 + 1]; } return getNearJieQi(true, conditions, wholeDay); } /** * 获取上一气令(逆推的第一个气令) * * @return 节气 */ public JieQi getPrevQi() { return getPrevQi(false); } /** * 获取上一气令(逆推的第一个气令) * * @param wholeDay 是否按天计 * @return 节气 */ public JieQi getPrevQi(boolean wholeDay) { int l = JIE_QI_IN_USE.length / 2; String[] conditions = new String[l]; for (int i = 0; i < l; i++) { conditions[i] = JIE_QI_IN_USE[i * 2 + 1]; } return getNearJieQi(false, conditions, wholeDay); } /** * 获取下一节气(顺推的第一个节气) * * @return 节气 */ public JieQi getNextJieQi() { return getNextJieQi(false); } /** * 获取下一节气(顺推的第一个节气) * * @param wholeDay 是否按天计 * @return 节气 */ public JieQi getNextJieQi(boolean wholeDay) { return getNearJieQi(true, null, wholeDay); } /** * 获取上一节气(逆推的第一个节气) * * @return 节气 */ public JieQi getPrevJieQi() { return getPrevJieQi(false); } /** * 获取上一节气(逆推的第一个节气) * * @param wholeDay 是否按天计 * @return 节气 */ public JieQi getPrevJieQi(boolean wholeDay) { return getNearJieQi(false, null, wholeDay); } /** * 获取最近的节气,如果未找到匹配的,返回null * * @param forward 是否顺推,true为顺推,false为逆推 * @param conditions 过滤条件,如果设置过滤条件,仅返回匹配该名称的 * @param wholeDay 是否按天计 * @return 节气 */ protected JieQi getNearJieQi(boolean forward, String[] conditions, boolean wholeDay) { String name = null; Solar near = null; Set filters = new HashSet(); if (null != conditions) { Collections.addAll(filters, conditions); } boolean filter = !filters.isEmpty(); String today = wholeDay ? solar.toYmd() : solar.toYmdHms(); for (Map.Entry entry : jieQi.entrySet()) { String jq = convertJieQi(entry.getKey()); if (filter) { if (!filters.contains(jq)) { continue; } } Solar solar = entry.getValue(); String day = wholeDay ? solar.toYmd() : solar.toYmdHms(); if (forward) { if (day.compareTo(today) <= 0) { continue; } if (null == near) { name = jq; near = solar; } else { String nearDay = wholeDay ? near.toYmd() : near.toYmdHms(); if (day.compareTo(nearDay) < 0) { name = jq; near = solar; } } } else { if (day.compareTo(today) > 0) { continue; } if (null == near) { name = jq; near = solar; } else { String nearDay = wholeDay ? near.toYmd() : near.toYmdHms(); if (day.compareTo(nearDay) > 0) { name = jq; near = solar; } } } } if (null == near) { return null; } return new JieQi(name, near); } /** * 获取节气名称,如果无节气,返回空字符串 * * @return 节气名称 */ public String getJieQi() { for (Map.Entry jq : jieQi.entrySet()) { Solar d = jq.getValue(); if (d.getYear() == solar.getYear() && d.getMonth() == solar.getMonth() && d.getDay() == solar.getDay()) { return convertJieQi(jq.getKey()); } } return ""; } /** * 获取当天节气对象,如果无节气,返回null * * @return 节气对象 */ public JieQi getCurrentJieQi() { for (Map.Entry jq : jieQi.entrySet()) { Solar d = jq.getValue(); if (d.getYear() == solar.getYear() && d.getMonth() == solar.getMonth() && d.getDay() == solar.getDay()) { return new JieQi(convertJieQi(jq.getKey()), d); } } return null; } /** * 获取当天节令对象,如果无节令,返回null * * @return 节气对象 */ public JieQi getCurrentJie() { for (int i = 0, j = JIE_QI_IN_USE.length; i < j; i += 2) { String key = JIE_QI_IN_USE[i]; Solar d = jieQi.get(key); if (d.getYear() == solar.getYear() && d.getMonth() == solar.getMonth() && d.getDay() == solar.getDay()) { return new JieQi(convertJieQi(key), d); } } return null; } /** * 获取当天气令对象,如果无气令,返回null * * @return 节气对象 */ public JieQi getCurrentQi() { for (int i = 1, j = JIE_QI_IN_USE.length; i < j; i += 2) { String key = JIE_QI_IN_USE[i]; Solar d = jieQi.get(key); if (d.getYear() == solar.getYear() && d.getMonth() == solar.getMonth() && d.getDay() == solar.getDay()) { return new JieQi(convertJieQi(key), d); } } return null; } public String toFullString() { StringBuilder s = new StringBuilder(); s.append(this); s.append(" "); s.append(getYearInGanZhi()); s.append("("); s.append(getYearShengXiao()); s.append(")年 "); s.append(getMonthInGanZhi()); s.append("("); s.append(getMonthShengXiao()); s.append(")月 "); s.append(getDayInGanZhi()); s.append("("); s.append(getDayShengXiao()); s.append(")日 "); s.append(getTimeZhi()); s.append("("); s.append(getTimeShengXiao()); s.append(")时 纳音["); s.append(getYearNaYin()); s.append(" "); s.append(getMonthNaYin()); s.append(" "); s.append(getDayNaYin()); s.append(" "); s.append(getTimeNaYin()); s.append("] 星期"); s.append(getWeekInChinese()); for (String f : getFestivals()) { s.append(" ("); s.append(f); s.append(")"); } for (String f : getOtherFestivals()) { s.append(" ("); s.append(f); s.append(")"); } String jq = getJieQi(); if (jq.length() > 0) { s.append(" ["); s.append(jq); s.append("]"); } s.append(" "); s.append(getGong()); s.append("方"); s.append(getShou()); s.append(" 星宿["); s.append(getXiu()); s.append(getZheng()); s.append(getAnimal()); s.append("]("); s.append(getXiuLuck()); s.append(") 彭祖百忌["); s.append(getPengZuGan()); s.append(" "); s.append(getPengZuZhi()); s.append("] 喜神方位["); s.append(getDayPositionXi()); s.append("]("); s.append(getDayPositionXiDesc()); s.append(") 阳贵神方位["); s.append(getDayPositionYangGui()); s.append("]("); s.append(getDayPositionYangGuiDesc()); s.append(") 阴贵神方位["); s.append(getDayPositionYinGui()); s.append("]("); s.append(getDayPositionYinGuiDesc()); s.append(") 福神方位["); s.append(getDayPositionFu()); s.append("]("); s.append(getDayPositionFuDesc()); s.append(") 财神方位["); s.append(getDayPositionCai()); s.append("]("); s.append(getDayPositionCaiDesc()); s.append(") 冲["); s.append(getDayChongDesc()); s.append("] 煞["); s.append(getDaySha()); s.append("]"); return s.toString(); } @Override public String toString() { return getYearInChinese() + "年" + getMonthInChinese() + "月" + getDayInChinese(); } /** * 获取年份 * * @return 如2015 */ public int getYear() { return year; } /** * 获取月份 * * @return 1到12,负数为闰月 */ public int getMonth() { return month; } /** * 获取日期 * * @return 日期 */ public int getDay() { return day; } /** * 获取小时 * * @return 0到23之间的数字 */ public int getHour() { return hour; } /** * 获取分钟 * * @return 0到59之间的数字 */ public int getMinute() { return minute; } /** * 获取秒钟 * * @return 0到59之间的数字 */ public int getSecond() { return second; } public int getTimeGanIndex() { return timeGanIndex; } public int getTimeZhiIndex() { return timeZhiIndex; } public int getDayGanIndex() { return dayGanIndex; } public int getDayZhiIndex() { return dayZhiIndex; } public int getMonthGanIndex() { return monthGanIndex; } public int getMonthZhiIndex() { return monthZhiIndex; } public int getYearGanIndex() { return yearGanIndex; } public int getYearZhiIndex() { return yearZhiIndex; } public int getYearGanIndexByLiChun() { return yearGanIndexByLiChun; } public int getYearZhiIndexByLiChun() { return yearZhiIndexByLiChun; } public int getDayGanIndexExact() { return dayGanIndexExact; } public int getDayGanIndexExact2() { return dayGanIndexExact2; } public int getDayZhiIndexExact() { return dayZhiIndexExact; } public int getDayZhiIndexExact2() { return dayZhiIndexExact2; } public int getMonthGanIndexExact() { return monthGanIndexExact; } public int getMonthZhiIndexExact() { return monthZhiIndexExact; } public int getYearGanIndexExact() { return yearGanIndexExact; } public int getYearZhiIndexExact() { return yearZhiIndexExact; } public Solar getSolar() { return solar; } public EightChar getEightChar() { if (null == eightChar) { eightChar = new EightChar(this); } return eightChar; } /** * 获取往后推几天的农历日期,如果要往前推,则天数用负数 * * @param days 天数 * @return 农历日期 */ public Lunar next(int days) { return solar.next(days).getLunar(); } /** * 获取年所在旬(以正月初一作为新年的开始) * * @return 旬 */ public String getYearXun() { return LunarUtil.getXun(getYearInGanZhi()); } /** * 获取年所在旬(以立春当天作为新年的开始) * * @return 旬 */ public String getYearXunByLiChun() { return LunarUtil.getXun(getYearInGanZhiByLiChun()); } /** * 获取年所在旬(以立春交接时刻作为新年的开始) * * @return 旬 */ public String getYearXunExact() { return LunarUtil.getXun(getYearInGanZhiExact()); } /** * 获取值年空亡(以正月初一作为新年的开始) * * @return 空亡(旬空) */ public String getYearXunKong() { return LunarUtil.getXunKong(getYearInGanZhi()); } /** * 获取值年空亡(以立春当天作为新年的开始) * * @return 空亡(旬空) */ public String getYearXunKongByLiChun() { return LunarUtil.getXunKong(getYearInGanZhiByLiChun()); } /** * 获取值年空亡(以立春交接时刻作为新年的开始) * * @return 空亡(旬空) */ public String getYearXunKongExact() { return LunarUtil.getXunKong(getYearInGanZhiExact()); } /** * 获取月所在旬(以节交接当天起算) * * @return 旬 */ public String getMonthXun() { return LunarUtil.getXun(getMonthInGanZhi()); } /** * 获取月所在旬(以节交接时刻起算) * * @return 旬 */ public String getMonthXunExact() { return LunarUtil.getXun(getMonthInGanZhiExact()); } /** * 获取值月空亡(以节交接当天起算) * * @return 空亡(旬空) */ public String getMonthXunKong() { return LunarUtil.getXunKong(getMonthInGanZhi()); } /** * 获取值月空亡(以节交接时刻起算) * * @return 空亡(旬空) */ public String getMonthXunKongExact() { return LunarUtil.getXunKong(getMonthInGanZhiExact()); } /** * 获取日所在旬(以节交接当天起算) * * @return 旬 */ public String getDayXun() { return LunarUtil.getXun(getDayInGanZhi()); } /** * 获取日所在旬(晚子时日柱算明天) * * @return 旬 */ public String getDayXunExact() { return LunarUtil.getXun(getDayInGanZhiExact()); } /** * 获取日所在旬(晚子时日柱算当天) * * @return 旬 */ public String getDayXunExact2() { return LunarUtil.getXun(getDayInGanZhiExact2()); } /** * 获取值日空亡 * * @return 空亡(旬空) */ public String getDayXunKong() { return LunarUtil.getXunKong(getDayInGanZhi()); } /** * 获取值日空亡(晚子时日柱算明天) * * @return 空亡(旬空) */ public String getDayXunKongExact() { return LunarUtil.getXunKong(getDayInGanZhiExact()); } /** * 获取值日空亡(晚子时日柱算当天) * * @return 空亡(旬空) */ public String getDayXunKongExact2() { return LunarUtil.getXunKong(getDayInGanZhiExact2()); } /** * 获取时辰所在旬 * * @return 旬 */ public String getTimeXun() { return LunarUtil.getXun(getTimeInGanZhi()); } /** * 获取值时空亡 * * @return 空亡(旬空) */ public String getTimeXunKong() { return LunarUtil.getXunKong(getTimeInGanZhi()); } /** * 获取数九 * * @return 数九,如果不是数九天,返回null */ public ShuJiu getShuJiu() { Solar current = Solar.fromYmd(solar.getYear(), solar.getMonth(), solar.getDay()); Solar start = jieQi.get("DONG_ZHI"); start = Solar.fromYmd(start.getYear(), start.getMonth(), start.getDay()); if (current.isBefore(start)) { start = jieQi.get("冬至"); start = Solar.fromYmd(start.getYear(), start.getMonth(), start.getDay()); } Solar end = Solar.fromYmd(start.getYear(), start.getMonth(), start.getDay()).next(81); if (current.isBefore(start) || !current.isBefore(end)) { return null; } int days = current.subtract(start); return new ShuJiu(LunarUtil.NUMBER[days / 9 + 1] + "九", days % 9 + 1); } /** * 获取三伏 * * @return 三伏,如果不是伏天,返回null */ public Fu getFu() { Solar current = Solar.fromYmd(solar.getYear(), solar.getMonth(), solar.getDay()); Solar xiaZhi = jieQi.get("夏至"); Solar liQiu = jieQi.get("立秋"); Solar start = Solar.fromYmd(xiaZhi.getYear(), xiaZhi.getMonth(), xiaZhi.getDay()); // 第1个庚日 int add = 6 - xiaZhi.getLunar().getDayGanIndex(); if (add < 0) { add += 10; } // 第3个庚日,即初伏第1天 add += 20; start = start.next(add); // 初伏以前 if (current.isBefore(start)) { return null; } int days = current.subtract(start); if (days < 10) { return new Fu("初伏", days + 1); } // 第4个庚日,中伏第1天 start = start.next(10); days = current.subtract(start); if (days < 10) { return new Fu("中伏", days + 1); } // 第5个庚日,中伏第11天或末伏第1天 start = start.next(10); days = current.subtract(start); Solar liQiuSolar = Solar.fromYmd(liQiu.getYear(), liQiu.getMonth(), liQiu.getDay()); // 末伏 if (liQiuSolar.isAfter(start)) { // 中伏 if (days < 10) { return new Fu("中伏", days + 11); } // 末伏第1天 start = start.next(10); days = current.subtract(start); } if (days < 10) { return new Fu("末伏", days + 1); } return null; } /** * 获取六曜 * * @return 六曜 */ public String getLiuYao() { return LunarUtil.LIU_YAO[(Math.abs(month) - 1 + day - 1) % 6]; } /** * 获取物候 * * @return 物候 */ public String getWuHou() { JieQi jieQi = getPrevJieQi(true); int offset = 0; for (int i = 0, j = JIE_QI.length; i < j; i++) { if (jieQi.getName().equals(JIE_QI[i])) { offset = i; break; } } int index = solar.subtract(jieQi.getSolar()) / 5; if (index > 2) { index = 2; } return LunarUtil.WU_HOU[(offset * 3 + index) % LunarUtil.WU_HOU.length]; } /** * 获取候 * * @return 候 */ public String getHou() { JieQi jieQi = getPrevJieQi(true); int max = LunarUtil.HOU.length - 1; int offset = solar.subtract(jieQi.getSolar()) / 5; if (offset > max) { offset = max; } return String.format("%s %s", jieQi.getName(), LunarUtil.HOU[offset]); } /** * 获取日禄 * * @return 日禄 */ public String getDayLu() { String gan = LunarUtil.LU.get(getDayGan()); String zhi = LunarUtil.LU.get(getDayZhi()); String lu = gan + "命互禄"; if (null != zhi) { lu += " " + zhi + "命进禄"; } return lu; } /** * 获取时辰 * * @return 时辰 */ public LunarTime getTime() { return new LunarTime(year, month, day, hour, minute, second); } /** * 获取当天的时辰列表 * * @return 时辰列表 */ public List getTimes() { List l = new ArrayList(); l.add(new LunarTime(year, month, day, 0, 0, 0)); for (int i = 0; i < 12; i++) { l.add(new LunarTime(year, month, day, (i + 1) * 2 - 1, 0, 0)); } return l; } /** * 获取佛历 * * @return 佛历 */ public Foto getFoto() { return Foto.fromLunar(this); } /** * 获取道历 * * @return 佛历 */ public Tao getTao() { return Tao.fromLunar(this); } }