diff --git a/README.md b/README.md index e610d58..5e121a1 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ lunar是一款无第三方依赖的公历(阳历)和农历(阴历、老黄历) cn.6tail lunar - 1.2.5 + 1.2.6 ``` diff --git a/README_EN.md b/README_EN.md index 0b04fbb..a40216e 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.5 + 1.2.6 ``` diff --git a/pom.xml b/pom.xml index 7e61add..b38ad66 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ cn.6tail lunar jar - 1.2.5 + 1.2.6 ${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 9e3b106..636aec8 100644 --- a/src/main/java/com/nlf/calendar/Lunar.java +++ b/src/main/java/com/nlf/calendar/Lunar.java @@ -2604,4 +2604,42 @@ public String getWuHou() { int days = (int) ((currentCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / MS_PER_DAY); return LunarUtil.WU_HOU[(offset * 3 + days / 5) % LunarUtil.WU_HOU.length]; } + + /** + * 获取日禄 + * @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; + } + } diff --git a/src/main/java/com/nlf/calendar/LunarTime.java b/src/main/java/com/nlf/calendar/LunarTime.java new file mode 100644 index 0000000..3d27827 --- /dev/null +++ b/src/main/java/com/nlf/calendar/LunarTime.java @@ -0,0 +1,373 @@ +package com.nlf.calendar; + +import com.nlf.calendar.util.LunarUtil; + +import java.util.List; +import java.util.Map; + +/** + * 时辰 + * + * @author 6tail + */ +public class LunarTime { + + /** + * 天干下标,0-9 + */ + private int ganIndex; + + /** + * 地支下标,0-11 + */ + private int zhiIndex; + + /** + * 阴历 + */ + private Lunar lunar; + + public LunarTime(int lunarYear, int lunarMonth, int lunarDay, int hour, int minute, int second) { + this.lunar = Lunar.fromYmdHms(lunarYear, lunarMonth, lunarDay, hour, minute, second); + this.zhiIndex = LunarUtil.getTimeZhiIndex(String.format("%02d:%02d", hour, minute)); + this.ganIndex = (lunar.getDayGanIndexExact() % 5 * 2 + zhiIndex) % 10; + } + + public static LunarTime fromYmdHms(int lunarYear, int lunarMonth, int lunarDay, int hour, int minute, int second) { + return new LunarTime(lunarYear, lunarMonth, lunarDay, hour, minute, second); + } + + public int getGanIndex() { + return ganIndex; + } + + public int getZhiIndex() { + return zhiIndex; + } + + /** + * 获取生肖 + * + * @return 生肖,如虎 + */ + public String getShengXiao() { + return LunarUtil.SHENGXIAO[zhiIndex + 1]; + } + + /** + * 获取地支 + * + * @return 地支 + */ + public String getZhi() { + return LunarUtil.ZHI[zhiIndex + 1]; + } + + /** + * 获取天干 + * + * @return 天干 + */ + public String getGan() { + return LunarUtil.GAN[ganIndex + 1]; + } + + /** + * 获取干支(时柱) + * + * @return 干支(时柱) + */ + public String getGanZhi() { + return getGan() + getZhi(); + } + + /** + * 获取喜神方位 + * + * @return 喜神方位,如艮 + */ + public String getPositionXi() { + return LunarUtil.POSITION_XI[ganIndex + 1]; + } + + /** + * 获取喜神方位描述 + * + * @return 喜神方位描述,如东北 + */ + public String getPositionXiDesc() { + return LunarUtil.POSITION_DESC.get(getPositionXi()); + } + + /** + * 获取阳贵神方位 + * + * @return 阳贵神方位,如艮 + */ + public String getPositionYangGui() { + return LunarUtil.POSITION_YANG_GUI[ganIndex + 1]; + } + + /** + * 获取阳贵神方位描述 + * + * @return 阳贵神方位描述,如东北 + */ + public String getPositionYangGuiDesc() { + return LunarUtil.POSITION_DESC.get(getPositionYangGui()); + } + + /** + * 获取阴贵神方位 + * + * @return 阴贵神方位,如艮 + */ + public String getPositionYinGui() { + return LunarUtil.POSITION_YIN_GUI[ganIndex + 1]; + } + + /** + * 获取阴贵神方位描述 + * + * @return 阴贵神方位描述,如东北 + */ + public String getPositionYinGuiDesc() { + return LunarUtil.POSITION_DESC.get(getPositionYinGui()); + } + + /** + * 获取福神方位 + * + * @return 福神方位,如艮 + */ + public String getPositionFu() { + return LunarUtil.POSITION_FU[ganIndex + 1]; + } + + /** + * 获取福神方位描述 + * + * @return 福神方位描述,如东北 + */ + public String getPositionFuDesc() { + return LunarUtil.POSITION_DESC.get(getPositionFu()); + } + + /** + * 获取财神方位 + * + * @return 财神方位,如艮 + */ + public String getPositionCai() { + return LunarUtil.POSITION_CAI[ganIndex + 1]; + } + + /** + * 获取财神方位描述 + * + * @return 财神方位描述,如东北 + */ + public String getPositionCaiDesc() { + return LunarUtil.POSITION_DESC.get(getPositionCai()); + } + + /** + * 获取纳音 + * + * @return 纳音,如剑锋金 + */ + public String getNaYin() { + return LunarUtil.NAYIN.get(getGanZhi()); + } + + /** + * 获取值时天神 + * + * @return 值时天神 + */ + public String getTianShen() { + String dayZhi = lunar.getDayZhiExact(); + int offset = LunarUtil.ZHI_TIAN_SHEN_OFFSET.get(dayZhi); + return LunarUtil.TIAN_SHEN[(zhiIndex + offset) % 12 + 1]; + } + + /** + * 获取值时天神类型:黄道/黑道 + * + * @return 值时天神类型:黄道/黑道 + */ + public String getTianShenType() { + return LunarUtil.TIAN_SHEN_TYPE.get(getTianShen()); + } + + /** + * 获取值时天神吉凶 + * + * @return 吉/凶 + */ + public String getTianShenLuck() { + return LunarUtil.TIAN_SHEN_TYPE_LUCK.get(getTianShenType()); + } + + /** + * 获取时冲 + * + * @return 时冲,如申 + */ + public String getChong() { + return LunarUtil.CHONG[zhiIndex + 1]; + } + + /** + * 获取时煞 + * + * @return 时煞,如北 + */ + public String getSha() { + return LunarUtil.SHA.get(getZhi()); + } + + /** + * 获取时冲生肖 + * + * @return 时冲生肖,如猴 + */ + public String getChongShengXiao() { + String chong = getChong(); + 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 getChongDesc() { + return "(" + getChongGan() + getChong() + ")" + getChongShengXiao(); + } + + /** + * 获取无情之克的时冲天干 + * + * @return 无情之克的时冲天干,如甲 + */ + public String getChongGan() { + return LunarUtil.CHONG_GAN[ganIndex + 1]; + } + + /** + * 获取有情之克的时冲天干 + * + * @return 有情之克的时冲天干,如甲 + */ + public String getChongGanTie() { + return LunarUtil.CHONG_GAN_TIE[ganIndex + 1]; + } + + /** + * 获取宜,如果没有,返回["无"] + * + * @return 宜 + */ + public List getYi() { + return LunarUtil.getTimeYi(lunar.getDayInGanZhiExact(), getGanZhi()); + } + + /** + * 获取忌,如果没有,返回["无"] + * + * @return 忌 + */ + public List getJi() { + return LunarUtil.getTimeJi(lunar.getDayInGanZhiExact(), getGanZhi()); + } + + /** + * 获取值时九星(时家紫白星歌诀:三元时白最为佳,冬至阳生顺莫差,孟日七宫仲一白,季日四绿发萌芽,每把时辰起甲子,本时星耀照光华,时星移入中宫去,顺飞八方逐细查。夏至阴生逆回首,孟归三碧季加六,仲在九宫时起甲,依然掌中逆轮跨。) + * + * @return 值时九星 + */ + public NineStar getNineStar() { + //顺逆 + String solarYmd = lunar.getSolar().toYmd(); + Map jieQi = lunar.getJieQiTable(); + boolean asc = false; + if (solarYmd.compareTo(jieQi.get("冬至").toYmd()) >= 0 && solarYmd.compareTo(jieQi.get("夏至").toYmd()) < 0) { + asc = true; + } + int start = asc ? 7 : 3; + String dayZhi = lunar.getDayZhi(); + if ("子午卯酉".contains(dayZhi)) { + start = asc ? 1 : 9; + } else if ("辰戌丑未".contains(dayZhi)) { + start = asc ? 4 : 6; + } + int index = asc ? start + zhiIndex - 1 : start - zhiIndex - 1; + if (index > 8) { + index -= 9; + } + if (index < 0) { + index += 9; + } + return new NineStar(index); + } + + /** + * 获取所在旬 + * + * @return 旬 + */ + public String getXun() { + return LunarUtil.getXun(getGanZhi()); + } + + /** + * 获取值时空亡 + * + * @return 空亡(旬空) + */ + public String getXunKong() { + return LunarUtil.getXunKong(getGanZhi()); + } + + /** + * 获取当前时辰的最早时分 + * + * @return 时分,如:21:00 + */ + public String getMinHm() { + int hour = lunar.getHour(); + if (hour <1){ + return "00:00"; + } else if (hour > 22) { + return "23:00"; + } + return String.format("%02d:00", hour % 2 == 0? hour - 1 : hour); + } + + /** + * 获取当前时辰的最晚时分 + * + * @return 时分,如:22:59 + */ + public String getMaxHm() { + int hour = lunar.getHour(); + if (hour <1){ + return "00:59"; + } else if (hour > 22) { + return "23:59"; + } + return String.format("%02d:59", hour % 2 == 0? hour : hour + 1); + } + + @Override + public String toString() { + return getGanZhi(); + } + +} diff --git a/src/main/java/com/nlf/calendar/LunarYear.java b/src/main/java/com/nlf/calendar/LunarYear.java index 33a541d..a467bca 100644 --- a/src/main/java/com/nlf/calendar/LunarYear.java +++ b/src/main/java/com/nlf/calendar/LunarYear.java @@ -1,5 +1,6 @@ package com.nlf.calendar; +import com.nlf.calendar.util.LunarUtil; import com.nlf.calendar.util.ShouXingUtil; import java.util.ArrayList; @@ -211,6 +212,58 @@ public int getLeapMonth() { return 0; } + /** + * 获取治水(正月第一个辰日是初几,就是几龙治水) + * + * @return 治水,如:二龙治水 + */ + public String getZhiShui() { + int offset = 4 - Solar.fromJulianDay(getMonth(1).getFirstJulianDay()).getLunar().getDayZhiIndex(); + if (offset < 0) { + offset += 12; + } + return LunarUtil.NUMBER[offset+1] + "龙治水"; + } + + /** + * 获取分饼(正月第一个丙日是初几,就是几人分饼) + * + * @return 分饼,如:六人分饼 + */ + public String getFenBing() { + int offset = 2 - Solar.fromJulianDay(getMonth(1).getFirstJulianDay()).getLunar().getDayGanIndex(); + if (offset < 0) { + offset += 10; + } + return LunarUtil.NUMBER[offset+1] + "人分饼"; + } + + /** + * 获取耕田(正月第一个丑日是初几,就是几牛耕田) + * + * @return 耕田,如:六牛耕田 + */ + public String getGengTian() { + int offset = 1 - Solar.fromJulianDay(getMonth(1).getFirstJulianDay()).getLunar().getDayZhiIndex(); + if (offset < 0) { + offset += 12; + } + return LunarUtil.NUMBER[offset+1] + "牛耕田"; + } + + /** + * 获取得金(正月第一个辛日是初几,就是几日得金) + * + * @return 得金,如:一日得金 + */ + public String getDeJin() { + int offset = 7 - Solar.fromJulianDay(getMonth(1).getFirstJulianDay()).getLunar().getDayGanIndex(); + if (offset < 0) { + offset += 10; + } + return LunarUtil.NUMBER[offset+1] + "日得金"; + } + @Override public String toString() { return year + ""; diff --git a/src/main/java/com/nlf/calendar/util/LunarUtil.java b/src/main/java/com/nlf/calendar/util/LunarUtil.java index ef6945b..0f7b8a3 100644 --- a/src/main/java/com/nlf/calendar/util/LunarUtil.java +++ b/src/main/java/com/nlf/calendar/util/LunarUtil.java @@ -105,7 +105,7 @@ public class LunarUtil{ /** 彭祖百忌.地支 */ public static final String[] PENGZU_ZHI = {"","子不问卜自惹祸殃","丑不冠带主不还乡","寅不祭祀神鬼不尝","卯不穿井水泉不香","辰不哭泣必主重丧","巳不远行财物伏藏","午不苫盖屋主更张","未不服药毒气入肠","申不安床鬼祟入房","酉不会客醉坐颠狂","戌不吃犬作怪上床","亥不嫁娶不利新郎"}; /** 数字 */ - public static final String[] NUMBER = {"〇","一","二","三","四","五","六","七","八","九"}; + public static final String[] NUMBER = {"〇","一","二","三","四","五","六","七","八","九","十","十一","十二"}; /** 月 */ public static final String[] MONTH = {"","正","二","三","四","五","六","七","八","九","十","冬","腊"}; /** 季节 */ @@ -1097,6 +1097,32 @@ public class LunarUtil{ } }; + /** 禄(甲禄在寅,乙禄在卯,丙戊禄在巳、丁己禄在午、庚禄在申、辛禄在酉、壬禄在亥、癸禄在子) */ + public static final Map LU = new HashMap(){ + private static final long serialVersionUID = -1L; + { + put("甲","寅"); + put("乙","卯"); + put("丙","巳"); + put("丁","午"); + put("戊","巳"); + put("己","午"); + put("庚","申"); + put("辛","酉"); + put("壬","亥"); + put("癸","子"); + + put("寅","甲"); + put("卯","乙"); + put("巳","丙,戊"); + put("午","丁,己"); + put("申","庚"); + put("酉","辛"); + put("亥","壬"); + put("子","癸"); + } + }; + protected LunarUtil(){} /** diff --git a/src/test/java/sample/BaZiTestNew.java b/src/test/java/sample/BaZiTestNew.java index f83ddce..e1a292d 100644 --- a/src/test/java/sample/BaZiTestNew.java +++ b/src/test/java/sample/BaZiTestNew.java @@ -108,6 +108,15 @@ public void testBazi2Solar2() { } } + @Test + public void testBazi2Solar3() { + List l = Solar.fromBaZi("辛丑", "丁酉", "丙寅", "戊戌"); + // [2021-09-15 20:00:00 星期三 处女座, 1961-09-30 20:00:00 星期六 天秤座] + for (Solar solar : l) { + System.out.println(solar.toFullString()); + } + } + @Test public void testBaziShiShenZhi() { Solar solar = new Solar(2020, 1, 1, 22, 35, 0); diff --git a/src/test/java/test/LunarTest.java b/src/test/java/test/LunarTest.java index 0a51c7d..1880ec7 100644 --- a/src/test/java/test/LunarTest.java +++ b/src/test/java/test/LunarTest.java @@ -331,4 +331,25 @@ public void test44() { Assert.assertEquals("猴", lunar.getYearShengXiao()); } + @Test + public void test45() { + Solar solar = Solar.fromYmd(1946, 9, 30); + Lunar lunar = solar.getLunar(); + Assert.assertEquals("一九四六年九月初六", lunar.toString()); + } + + @Test + public void test46() { + Solar solar = Solar.fromYmd(1946, 9, 29); + Lunar lunar = solar.getLunar(); + Assert.assertEquals("一九四六年九月初五", lunar.toString()); + } + + @Test + public void test47() { + Solar solar = Solar.fromYmd(2017, 2, 15); + Lunar lunar = solar.getLunar(); + Assert.assertEquals("子命互禄 辛命进禄", lunar.getDayLu()); + } + } diff --git a/src/test/java/test/YearTest.java b/src/test/java/test/YearTest.java index 817887d..34ab75a 100644 --- a/src/test/java/test/YearTest.java +++ b/src/test/java/test/YearTest.java @@ -1,5 +1,6 @@ package test; +import com.nlf.calendar.LunarYear; import com.nlf.calendar.SolarYear; import org.junit.Assert; import org.junit.Test; @@ -21,4 +22,43 @@ public void test(){ Assert.assertEquals("2020年",year.next(1).toFullString()); } + @Test + public void test1(){ + LunarYear year = new LunarYear(2017); + Assert.assertEquals("二龙治水",year.getZhiShui()); + + year = new LunarYear(2018); + Assert.assertEquals("二龙治水",year.getZhiShui()); + + year = new LunarYear(2019); + Assert.assertEquals("八龙治水",year.getZhiShui()); + + year = new LunarYear(5); + Assert.assertEquals("三龙治水",year.getZhiShui()); + } + + @Test + public void test2(){ + LunarYear year = new LunarYear(2017); + Assert.assertEquals("二人分饼",year.getFenBing()); + + year = new LunarYear(2018); + Assert.assertEquals("八人分饼",year.getFenBing()); + + year = new LunarYear(5); + Assert.assertEquals("一人分饼",year.getFenBing()); + } + + @Test + public void test3(){ + LunarYear year = new LunarYear(2021); + Assert.assertEquals("十一牛耕田",year.getGengTian()); + } + + @Test + public void test4(){ + LunarYear year = new LunarYear(2018); + Assert.assertEquals("三日得金",year.getDeJin()); + } + }