From 3e256ddbd3a9cf7fca7894d05400974a775ddf8d Mon Sep 17 00:00:00 2001 From: 6tail <6tail@6tail.cn> Date: Fri, 7 Jan 2022 20:29:04 +0800 Subject: [PATCH] =?UTF-8?q?v1.2.17=20=E4=BF=AE=E5=A4=8D=E4=B9=9D=E6=98=9F?= =?UTF-8?q?=E9=94=99=E8=AF=AF=EF=BC=9B=E4=BF=AE=E5=A4=8D=E5=A4=AA=E5=B2=81?= =?UTF-8?q?=E6=96=B9=E4=BD=8D=E9=94=99=E8=AF=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- README_EN.md | 2 +- pom.xml | 2 +- src/main/java/com/nlf/calendar/Lunar.java | 293 +++++++++++++++--- .../java/com/nlf/calendar/LunarMonth.java | 16 + src/main/java/com/nlf/calendar/LunarYear.java | 32 +- src/test/java/test/LunarTest.java | 4 +- 7 files changed, 300 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 12acca2..380a93e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ lunar是一款无第三方依赖的公历(阳历)、农历(阴历、老黄历) cn.6tail lunar - 1.2.16 + 1.2.17 ``` diff --git a/README_EN.md b/README_EN.md index 42a557a..fbec63d 100644 --- a/README_EN.md +++ b/README_EN.md @@ -12,7 +12,7 @@ lunar is a calendar library for Solar and Chinese Lunar. cn.6tail lunar - 1.2.16 + 1.2.17 ``` diff --git a/pom.xml b/pom.xml index 36acf0c..84b7fd4 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ cn.6tail lunar jar - 1.2.16 + 1.2.17 ${project.groupId}:${project.artifactId} https://github.com/6tail/lunar-java a calendar library for Solar and Chinese Lunar diff --git a/src/main/java/com/nlf/calendar/Lunar.java b/src/main/java/com/nlf/calendar/Lunar.java index c16df54..07c6e1e 100644 --- a/src/main/java/com/nlf/calendar/Lunar.java +++ b/src/main/java/com/nlf/calendar/Lunar.java @@ -1207,36 +1207,200 @@ public class Lunar { } /** - * 获取日太岁方位 + * 获取年太岁方位(默认流派2新年以立春零点起算) * - * @return 日太岁方位,如艮 + * @return 太岁方位,如艮 */ - public String getDayPositionTaiSui() { + 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; - String gz = getDayInGanZhi(); - if ("甲子,乙丑,丙寅,丁卯,戊辰,已巳".contains(gz)) { - p = "震"; - } else if ("丙子,丁丑,戊寅,已卯,庚辰,辛巳".contains(gz)) { - p = "离"; - } else if ("戊子,已丑,庚寅,辛卯,壬辰,癸巳".contains(gz)) { - p = "中"; - } else if ("庚子,辛丑,壬寅,癸卯,甲辰,乙巳".contains(gz)) { - p = "兑"; - } else if ("壬子,癸丑,甲寅,乙卯,丙辰,丁巳".contains(gz)) { - p = "坎"; - } else{ - p = LunarYear.fromYear(this.getYear()).getPositionTaiSui(); + int m = monthZhiIndex - LunarUtil.BASE_MONTH_ZHI_INDEX; + if (m < 0) { + m += 12; + } + switch(m) { + case 0: + case 4: + case 8: + p = "艮"; + break; + case 2: + case 6: + case 10: + p = "坤"; + break; + case 3: + case 7: + case 11: + p = "巽"; + break; + default: + p = LunarUtil.POSITION_GAN[monthGanIndex]; } return p; } /** - * 获取日太岁方位描述 + * 获取月太岁方位(默认流派2新的一月以节交接当天零点起算) * - * @return 日太岁方位描述,如东北 + * @return 太岁方位,如艮 + */ + public String getMonthPositionTaiSui() { + return getMonthPositionTaiSui(2); + } + + /** + * 获取月太岁方位 + * + * @param sect 流派:2为新的一月以节交接当天零点起算;3为新的一月以节交接准确时刻起算 + * @return 太岁方位,如艮 + */ + public String getMonthPositionTaiSui(int sect) { + int monthZhiIndex; + int monthGanIndex; + switch (sect) { + case 3: + monthZhiIndex = this.monthZhiIndexExact; + monthGanIndex = this.monthGanIndexExact; + break; + default: + 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 LunarUtil.POSITION_DESC.get(getDayPositionTaiSui()); + return getDayPositionTaiSuiDesc(2); + } + + /** + * 获取日太岁方位描述 + * + * @param sect 流派:2新年以立春零点起算;1新年以正月初一起算;3新年以立春节气交接的时刻起算 + * @return 太岁方位描述,如东北 + */ + public String getDayPositionTaiSuiDesc(int sect) { + return LunarUtil.POSITION_DESC.get(getDayPositionTaiSui(sect)); } /** @@ -1855,37 +2019,92 @@ public class Lunar { return LunarUtil.YUE_XIANG[day]; } + protected NineStar getYearNineStar(String yearInGanZhi) { + int index = LunarUtil.getJiaZiIndex(yearInGanZhi) + 1; + int yearOffset = 0; + if (index != LunarUtil.getJiaZiIndex(this.getYearInGanZhi()) + 1) { + yearOffset = -1; + } + int yuan = ((this.year + yearOffset + 2696) / 60) % 3; + int offset = (62 + yuan * 3 - index) % 9; + if(0 == offset){ + offset = 9; + } + return NineStar.fromIndex(offset - 1); + } + /** - * 获取值年九星(流年紫白星起例歌诀:年上吉星论甲子,逐年星逆中宫起;上中下作三元汇,一上四中七下兑。) + * 获取值年九星(默认流派2新年以立春零点起算。流年紫白星起例歌诀:年上吉星论甲子,逐年星逆中宫起;上中下作三元汇,一上四中七下兑。) * * @return 值年九星 */ public NineStar getYearNineStar() { - return LunarYear.fromYear(year).getNineStar(); + 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 n = 12; - String yearZhi = getYearZhi(); - if ("子午卯酉".contains(yearZhi)) { - n = 18; - } else if ("辰戌丑未".contains(yearZhi)) { - n = 15; + 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; } - int m = month; - if(m < 0){ - m = -m; - } - int offset = (n - m) % 9; - if(0 == offset){ - offset = 9; - } - return NineStar.fromIndex(offset - 1); + return getMonthNineStar(yearZhiIndex, monthZhiIndex); } /** diff --git a/src/main/java/com/nlf/calendar/LunarMonth.java b/src/main/java/com/nlf/calendar/LunarMonth.java index c07c9f8..f2b7186 100644 --- a/src/main/java/com/nlf/calendar/LunarMonth.java +++ b/src/main/java/com/nlf/calendar/LunarMonth.java @@ -132,6 +132,22 @@ public class LunarMonth { 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() { diff --git a/src/main/java/com/nlf/calendar/LunarYear.java b/src/main/java/com/nlf/calendar/LunarYear.java index 616b019..17ac6c0 100644 --- a/src/main/java/com/nlf/calendar/LunarYear.java +++ b/src/main/java/com/nlf/calendar/LunarYear.java @@ -214,6 +214,24 @@ public class LunarYear { return jieQiJulianDays; } + /** + * 获取天干序号,从0开始 + * + * @return 序号 + */ + public int getGanIndex() { + return ganIndex; + } + + /** + * 获取地支序号,从0开始 + * + * @return 序号 + */ + public int getZhiIndex() { + return zhiIndex; + } + /** * 获取天干 * @@ -436,15 +454,10 @@ public class LunarYear { * @return 九星 */ public NineStar getNineStar() { - int index = LunarUtil.getJiaZiIndex(this.getGanZhi()) + 1; - int n = 65; - if ("中元".equals(getYuan())) { - n = 68; - } else if ("下元".equals(getYuan())) { - n = 62; - } - int offset = (n - index) % 9; - if (0 == offset) { + int index = LunarUtil.getJiaZiIndex(getGanZhi()) + 1; + int yuan = ((this.year + 2696) / 60) % 3; + int offset = (62 + yuan * 3 - index) % 9; + if(0 == offset){ offset = 9; } return NineStar.fromIndex(offset - 1); @@ -586,4 +599,5 @@ public class LunarYear { public String toFullString() { return year + "年"; } + } diff --git a/src/test/java/test/LunarTest.java b/src/test/java/test/LunarTest.java index 48e0b2f..437f602 100644 --- a/src/test/java/test/LunarTest.java +++ b/src/test/java/test/LunarTest.java @@ -159,13 +159,13 @@ public class LunarTest { @Test public void test23() { Lunar lunar = Lunar.fromYmd(2022, 1, 1); - Assert.assertEquals("五黄土玉衡", lunar.getYearNineStar().toString()); + Assert.assertEquals("六白金开阳", lunar.getYearNineStar().toString()); } @Test public void test24() { Lunar lunar = Lunar.fromYmd(2033, 1, 1); - Assert.assertEquals("三碧木天玑", lunar.getYearNineStar().toString()); + Assert.assertEquals("四绿木天权", lunar.getYearNineStar().toString()); } @Test