From e010e64f1a2c6159777737d10dd418f037b4ec61 Mon Sep 17 00:00:00 2001 From: 6tail <6tail@6tail.cn> Date: Sun, 2 Jan 2022 17:36:12 +0800 Subject: [PATCH] =?UTF-8?q?v1.2.16=20=E8=A1=A5=E5=85=85=E7=81=B6=E9=A9=AC?= =?UTF-8?q?=E5=A4=B4=E7=9B=B8=E5=85=B3=E5=86=85=E5=AE=B9=EF=BC=9B=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=B9=9D=E6=98=9F=E9=94=99=E8=AF=AF=EF=BC=9B=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=A4=AA=E5=B2=81=E6=96=B9=E4=BD=8D=EF=BC=9B=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E9=81=93=E5=8E=86=E5=A4=A9=E8=B5=A6=E6=97=A5=EF=BC=9B?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=85=AB=E5=AD=97=E8=BD=AC=E9=98=B3=E5=8E=86?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=EF=BC=9B=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=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/ExactDate.java | 51 +++ src/main/java/com/nlf/calendar/Lunar.java | 180 +++++---- .../java/com/nlf/calendar/LunarMonth.java | 40 ++ src/main/java/com/nlf/calendar/LunarYear.java | 348 ++++++++++++++++-- src/main/java/com/nlf/calendar/NineStar.java | 150 +++++--- src/main/java/com/nlf/calendar/Solar.java | 2 +- src/main/java/com/nlf/calendar/Tao.java | 29 ++ .../java/com/nlf/calendar/util/LunarUtil.java | 10 +- .../java/com/nlf/calendar/util/SolarUtil.java | 33 ++ 12 files changed, 683 insertions(+), 166 deletions(-) diff --git a/README.md b/README.md index 2e29092..12acca2 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ lunar是一款无第三方依赖的公历(阳历)、农历(阴历、老黄历) cn.6tail lunar - 1.2.15 + 1.2.16 ``` diff --git a/README_EN.md b/README_EN.md index 5cfc94c..42a557a 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.15 + 1.2.16 ``` diff --git a/pom.xml b/pom.xml index 90caefa..36acf0c 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ cn.6tail lunar jar - 1.2.15 + 1.2.16 ${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/ExactDate.java b/src/main/java/com/nlf/calendar/ExactDate.java index e26a37e..1770488 100644 --- a/src/main/java/com/nlf/calendar/ExactDate.java +++ b/src/main/java/com/nlf/calendar/ExactDate.java @@ -1,5 +1,7 @@ package com.nlf.calendar; +import com.nlf.calendar.util.SolarUtil; + import java.util.Calendar; import java.util.Date; import java.util.TimeZone; @@ -20,6 +22,9 @@ public class ExactDate { Calendar c = Calendar.getInstance(TIME_ZONE); c.set(year, month - 1, day, hour, minute, second); c.set(Calendar.MILLISECOND, 0); + if (0 == year) { + c.add(Calendar.YEAR, 1); + } return c; } @@ -33,4 +38,50 @@ public class ExactDate { c.set(Calendar.MILLISECOND, 0); return c; } + + /** + * 获取两个日期之间相差的天数(如果日期a比日期b小,天数为正,如果日期a比日期b大,天数为负) + * + * @param ay 年a + * @param am 月a + * @param ad 日a + * @param by 年b + * @param bm 月b + * @param bd 日b + * @return 天数 + */ + public static int getDaysBetween(int ay, int am, int ad, int by, int bm, int bd) { + int n; + int days; + int i; + if (ay == by) { + n = SolarUtil.getDaysInYear(by, bm, bd) - SolarUtil.getDaysInYear(ay, am, ad); + } else if (ay > by) { + days = SolarUtil.getDaysOfYear(by) - SolarUtil.getDaysInYear(by, bm, bd); + for (i = by + 1; i < ay; i++) { + days += SolarUtil.getDaysOfYear(i); + } + days += SolarUtil.getDaysInYear(ay, am, ad); + n = -days; + } else { + days = SolarUtil.getDaysOfYear(ay) - SolarUtil.getDaysInYear(ay, am, ad); + for (i = ay + 1; i < by; i++) { + days += SolarUtil.getDaysOfYear(i); + } + days += SolarUtil.getDaysInYear(by, bm, bd); + n = days; + } + return n; + } + + /** + * 获取两个日期之间相差的天数(如果日期a比日期b小,天数为正,如果日期a比日期b大,天数为负) + * + * @param calendar0 日期a + * @param calendar1 日期b + * @return 天数 + */ + public static int getDaysBetween(Calendar calendar0, Calendar calendar1) { + return getDaysBetween(calendar0.get(Calendar.YEAR), calendar0.get(Calendar.MONTH) + 1, calendar0.get(Calendar.DATE), calendar1.get(Calendar.YEAR), calendar1.get(Calendar.MONTH) + 1, calendar1.get(Calendar.DATE)); + } } diff --git a/src/main/java/com/nlf/calendar/Lunar.java b/src/main/java/com/nlf/calendar/Lunar.java index 0ebf06c..c16df54 100644 --- a/src/main/java/com/nlf/calendar/Lunar.java +++ b/src/main/java/com/nlf/calendar/Lunar.java @@ -11,10 +11,6 @@ import java.util.*; * @author 6tail */ public class Lunar { - /** - * 1天对应的毫秒 - */ - private static final long MS_PER_DAY = 86400000L; /** * 节气表,国标以冬至为首个气令 */ @@ -198,18 +194,14 @@ public class Lunar { @SuppressWarnings("MagicConstant") public Lunar(Date date) { solar = new Solar(date); - Calendar c = ExactDate.fromYmd(solar.getYear(), solar.getMonth(), solar.getDay()); - long solarTime = c.getTimeInMillis(); - int y = solar.getYear(); - LunarYear ly = LunarYear.fromYear(y); + int currentYear = solar.getYear(); + int currentMonth = solar.getMonth(); + int currentDay = solar.getDay(); + LunarYear ly = LunarYear.fromYear(currentYear); for (LunarMonth m : ly.getMonths()) { // 初一 - Calendar firstDay = Solar.fromJulianDay(m.getFirstJulianDay()).getCalendar(); - firstDay.set(Calendar.HOUR_OF_DAY, 0); - firstDay.set(Calendar.MINUTE, 0); - firstDay.set(Calendar.SECOND, 0); - firstDay.set(Calendar.MILLISECOND, 0); - int days = (int) ((solarTime - firstDay.getTimeInMillis()) / MS_PER_DAY); + Solar firstDay = Solar.fromJulianDay(m.getFirstJulianDay()); + int days = ExactDate.getDaysBetween(firstDay.getYear(), firstDay.getMonth(), firstDay.getDay(), currentYear, currentMonth, currentDay); if (days < m.getDayCount()) { year = m.getYear(); month = m.getMonth(); @@ -1214,6 +1206,39 @@ public class Lunar { return LunarUtil.POSITION_DESC.get(getDayPositionCai()); } + /** + * 获取日太岁方位 + * + * @return 日太岁方位,如艮 + */ + public String getDayPositionTaiSui() { + 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(); + } + return p; + } + + /** + * 获取日太岁方位描述 + * + * @return 日太岁方位描述,如东北 + */ + public String getDayPositionTaiSuiDesc() { + return LunarUtil.POSITION_DESC.get(getDayPositionTaiSui()); + } + /** * 获取时辰喜神方位 * @@ -1836,11 +1861,7 @@ public class Lunar { * @return 值年九星 */ public NineStar getYearNineStar() { - int index = -(year - 1900) % 9; - if (index < 0) { - index += 9; - } - return new NineStar(index); + return LunarYear.fromYear(year).getNineStar(); } /** @@ -1849,23 +1870,22 @@ public class Lunar { * @return 值月九星 */ public NineStar getMonthNineStar() { - int start = 2; + int n = 12; String yearZhi = getYearZhi(); if ("子午卯酉".contains(yearZhi)) { - start = 8; + n = 18; } else if ("辰戌丑未".contains(yearZhi)) { - start = 5; + n = 15; } - // 寅月起,所以需要-2 - int monthIndex = monthZhiIndex - 2; - if (monthIndex < 0) { - monthIndex += 12; + int m = month; + if(m < 0){ + m = -m; } - int index = start - monthIndex - 1; - while (index < 0) { - index += 9; + int offset = (n - m) % 9; + if(0 == offset){ + offset = 9; } - return new NineStar(index); + return NineStar.fromIndex(offset - 1); } /** @@ -1874,40 +1894,45 @@ public class Lunar { * @return 值日九星 */ public NineStar getDayNineStar() { - //顺逆 String solarYmd = solar.toYmd(); - String dongZhi = jieQi.get("冬至").toYmd(); - String yuShui = jieQi.get("雨水").toYmd(); - String guYu = jieQi.get("谷雨").toYmd(); - String xiaZhi = jieQi.get("夏至").toYmd(); - String chuShu = jieQi.get("处暑").toYmd(); - String shuangJiang = jieQi.get("霜降").toYmd(); - - int start = 6; - boolean asc = false; - if (solarYmd.compareTo(dongZhi) >= 0 && solarYmd.compareTo(yuShui) < 0) { - asc = true; - start = 1; - } else if (solarYmd.compareTo(yuShui) >= 0 && solarYmd.compareTo(guYu) < 0) { - asc = true; - start = 7; - } else if (solarYmd.compareTo(guYu) >= 0 && solarYmd.compareTo(xiaZhi) < 0) { - asc = true; - start = 4; - } else if (solarYmd.compareTo(xiaZhi) >= 0 && solarYmd.compareTo(chuShu) < 0) { - start = 9; - } else if (solarYmd.compareTo(chuShu) >= 0 && solarYmd.compareTo(shuangJiang) < 0) { - start = 3; + 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); } - int ganZhiIndex = LunarUtil.getJiaZiIndex(getDayInGanZhi()) % 9; - int index = asc ? start + ganZhiIndex - 1 : start - ganZhiIndex - 1; - if (index > 8) { - index -= 9; + String solarShunBaiYmd = solarShunBai.toYmd(); + if (dongZhiIndex2>29) { + solarShunBai2 = dongZhi2.next(60 - dongZhiIndex2); + } else { + solarShunBai2 = dongZhi2.next(-dongZhiIndex2); } - if (index < 0) { - index += 9; + String solarShunBaiYmd2 = solarShunBai2.toYmd(); + if (xiaZhiIndex>29) { + solarNiZi = xiaZhi.next(60 - xiaZhiIndex); + } else { + solarNiZi = xiaZhi.next(-xiaZhiIndex); } - return new NineStar(index); + String solarNiZiYmd = solarNiZi.toYmd(); + int offset = 0; + if (solarYmd.compareTo(solarShunBaiYmd) >= 0 && solarYmd.compareTo(solarNiZiYmd) < 0) { + offset = ExactDate.getDaysBetween(solarShunBai.getCalendar(), this.getSolar().getCalendar()) % 9; + } else if (solarYmd.compareTo(solarNiZiYmd) >= 0 && solarYmd.compareTo(solarShunBaiYmd2) < 0){ + offset = 8 - (ExactDate.getDaysBetween(solarNiZi.getCalendar(), this.getSolar().getCalendar()) % 9); + } else if (solarYmd.compareTo(solarShunBaiYmd2) >= 0) { + offset = ExactDate.getDaysBetween(solarShunBai2.getCalendar(), this.getSolar().getCalendar()) % 9; + } else if (solarYmd.compareTo(solarShunBaiYmd) < 0) { + offset = (8 + ExactDate.getDaysBetween(this.getSolar().getCalendar(), solarShunBai.getCalendar())) % 9; + } + return NineStar.fromIndex(offset); } /** @@ -1916,27 +1941,22 @@ public class Lunar { * @return 值时九星 */ public NineStar getTimeNineStar() { - //顺逆 String solarYmd = solar.toYmd(); boolean asc = false; - if (solarYmd.compareTo(jieQi.get("冬至").toYmd()) >= 0 && solarYmd.compareTo(jieQi.get("夏至").toYmd()) < 0) { + 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 ? 7 : 3; + int start = asc ? 6 : 2; String dayZhi = getDayZhi(); if ("子午卯酉".contains(dayZhi)) { - start = asc ? 1 : 9; + start = asc ? 0 : 8; } else if ("辰戌丑未".contains(dayZhi)) { - start = asc ? 4 : 6; + start = asc ? 3 : 5; } - int index = asc ? start + timeZhiIndex - 1 : start - timeZhiIndex - 1; - if (index > 8) { - index -= 9; - } - if (index < 0) { - index += 9; - } - return new NineStar(index); + int index = asc ? start + timeZhiIndex : start + 9 - timeZhiIndex; + return new NineStar(index % 9); } /** @@ -2615,7 +2635,7 @@ public class Lunar { return null; } - int days = (int) ((currentCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / MS_PER_DAY); + int days = ExactDate.getDaysBetween(startCalendar, currentCalendar); return new ShuJiu(LunarUtil.NUMBER[days / 9 + 1] + "九", days % 9 + 1); } @@ -2644,7 +2664,7 @@ public class Lunar { return null; } - int days = (int) ((currentCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / MS_PER_DAY); + int days = ExactDate.getDaysBetween(startCalendar, currentCalendar); if (days < 10) { return new Fu("初伏", days + 1); } @@ -2652,7 +2672,7 @@ public class Lunar { // 第4个庚日,中伏第1天 startCalendar.add(Calendar.DATE, 10); - days = (int) ((currentCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / MS_PER_DAY); + days = ExactDate.getDaysBetween(startCalendar, currentCalendar); if (days < 10) { return new Fu("中伏", days + 1); } @@ -2662,7 +2682,7 @@ public class Lunar { Calendar liQiuCalendar = ExactDate.fromYmd(liQiu.getYear(), liQiu.getMonth(), liQiu.getDay()); - days = (int) ((currentCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / MS_PER_DAY); + days = ExactDate.getDaysBetween(startCalendar, currentCalendar); // 末伏 if (liQiuCalendar.compareTo(startCalendar) <= 0) { if (days < 10) { @@ -2675,7 +2695,7 @@ public class Lunar { } // 末伏第1天 startCalendar.add(Calendar.DATE, 10); - days = (int) ((currentCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / MS_PER_DAY); + days = ExactDate.getDaysBetween(startCalendar, currentCalendar); if (days < 10) { return new Fu("末伏", days + 1); } @@ -2713,7 +2733,7 @@ public class Lunar { Solar startSolar = jieQi.getSolar(); Calendar startCalendar = ExactDate.fromYmd(startSolar.getYear(), startSolar.getMonth(), startSolar.getDay()); - int days = (int) ((currentCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / MS_PER_DAY); + int days = ExactDate.getDaysBetween(startCalendar, currentCalendar); return LunarUtil.WU_HOU[(offset * 3 + days / 5) % LunarUtil.WU_HOU.length]; } @@ -2728,7 +2748,7 @@ public class Lunar { Calendar currentCalendar = ExactDate.fromYmd(solar.getYear(), solar.getMonth(), solar.getDay()); Solar startSolar = jieQi.getSolar(); Calendar startCalendar = ExactDate.fromYmd(startSolar.getYear(), startSolar.getMonth(), startSolar.getDay()); - int days = (int) ((currentCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / MS_PER_DAY); + int days = ExactDate.getDaysBetween(startCalendar, currentCalendar); return String.format("%s %s", name, LunarUtil.HOU[(days / 5) % LunarUtil.HOU.length]); } diff --git a/src/main/java/com/nlf/calendar/LunarMonth.java b/src/main/java/com/nlf/calendar/LunarMonth.java index f8d5990..c07c9f8 100644 --- a/src/main/java/com/nlf/calendar/LunarMonth.java +++ b/src/main/java/com/nlf/calendar/LunarMonth.java @@ -93,6 +93,46 @@ public class LunarMonth { return firstJulianDay; } + /** + * 获取太岁方位 + * + * @return 太岁方位,如艮 + */ + public String getPositionTaiSui() { + String p; + int m = Math.abs(month); + switch(m) { + case 1: + case 5: + case 9: + p = "艮"; + break; + case 3: + case 7: + case 11: + p = "坤"; + break; + case 4: + case 8: + case 12: + 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()); + } + + @Override public String toString() { return year + "年" + (isLeap() ? "闰" : "") + LunarUtil.MONTH[Math.abs(month)] + "月(" + dayCount + "天)"; diff --git a/src/main/java/com/nlf/calendar/LunarYear.java b/src/main/java/com/nlf/calendar/LunarYear.java index c4f590a..616b019 100644 --- a/src/main/java/com/nlf/calendar/LunarYear.java +++ b/src/main/java/com/nlf/calendar/LunarYear.java @@ -52,6 +52,16 @@ public class LunarYear { */ private int year; + /** + * 天干下标 + */ + private int ganIndex; + + /** + * 地支下标 + */ + private int zhiIndex; + /** * 农历月们 */ @@ -69,6 +79,17 @@ public class LunarYear { */ public LunarYear(int lunarYear) { this.year = lunarYear; + int offset = lunarYear - 4; + int yearGanIndex = offset % 10; + int yearZhiIndex = offset % 12; + if (yearGanIndex < 0) { + yearGanIndex += 10; + } + if (yearZhiIndex < 0) { + yearZhiIndex += 12; + } + this.ganIndex = yearGanIndex; + this.zhiIndex = yearZhiIndex; compute(); } @@ -193,6 +214,33 @@ public class LunarYear { return jieQiJulianDays; } + /** + * 获取天干 + * + * @return 天干 + */ + public String getGan() { + return LunarUtil.GAN[ganIndex + 1]; + } + + /** + * 获取地支 + * + * @return 地支 + */ + public String getZhi() { + return LunarUtil.ZHI[zhiIndex + 1]; + } + + /** + * 获取干支 + * + * @return 干支 + */ + public String getGanZhi() { + return getGan() + getZhi(); + } + /** * 获取农历月 * @@ -222,30 +270,38 @@ public class LunarYear { 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(); + protected String getZaoByGan(int index, String name) { + int offset = index - Solar.fromJulianDay(getMonth(1).getFirstJulianDay()).getLunar().getDayGanIndex(); if (offset < 0) { offset += 10; } - return LunarUtil.NUMBER[offset+1] + "人分饼"; + return name.replaceFirst("几", LunarUtil.NUMBER[offset + 1]); + } + + protected String getZaoByZhi(int index, String name) { + int offset = index - Solar.fromJulianDay(getMonth(1).getFirstJulianDay()).getLunar().getDayZhiIndex(); + if (offset < 0) { + offset += 12; + } + return name.replaceFirst("几", LunarUtil.NUMBER[offset + 1]); + } + + /** + * 获取几鼠偷粮 + * + * @return 几鼠偷粮 + */ + public String getTouLiang() { + return getZaoByZhi(0, "几鼠偷粮"); + } + + /** + * 获取草子几分 + * + * @return 草子几分 + */ + public String getCaoZi() { + return getZaoByZhi(0, "草子几分"); } /** @@ -254,11 +310,79 @@ public class LunarYear { * @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 getZaoByZhi(1, "几牛耕田"); + } + + /** + * 获取花收几分 + * + * @return 花收几分 + */ + public String getHuaShou() { + return getZaoByZhi(3, "花收几分"); + } + + /** + * 获取治水(正月第一个辰日是初几,就是几龙治水) + * + * @return 治水,如:二龙治水 + */ + public String getZhiShui() { + return getZaoByZhi(4, "几龙治水"); + } + + /** + * 获取几马驮谷 + * + * @return 几马驮谷 + */ + public String getTuoGu() { + return getZaoByZhi(6, "几马驮谷"); + } + + /** + * 获取几鸡抢米 + * + * @return 几鸡抢米 + */ + public String getQiangMi() { + return getZaoByZhi(9, "几鸡抢米"); + } + + /** + * 获取几姑看蚕 + * + * @return 几姑看蚕 + */ + public String getKanCan() { + return getZaoByZhi(9, "几姑看蚕"); + } + + /** + * 获取几屠共猪 + * + * @return 几屠共猪 + */ + public String getGongZhu() { + return getZaoByZhi(11, "几屠共猪"); + } + + /** + * 获取甲田几分 + * + * @return 甲田几分 + */ + public String getJiaTian() { + return getZaoByGan(0, "甲田几分"); + } + + /** + * 获取分饼(正月第一个丙日是初几,就是几人分饼) + * + * @return 分饼,如:六人分饼 + */ + public String getFenBing() { + return getZaoByGan(2, "几人分饼"); } /** @@ -267,11 +391,25 @@ public class LunarYear { * @return 得金,如:一日得金 */ public String getDeJin() { - int offset = 7 - Solar.fromJulianDay(getMonth(1).getFirstJulianDay()).getLunar().getDayGanIndex(); - if (offset < 0) { - offset += 10; - } - return LunarUtil.NUMBER[offset+1] + "日得金"; + return getZaoByGan(7, "几日得金"); + } + + /** + * 获取几人几丙 + * + * @return 几人几丙 + */ + public String getRenBing() { + return getZaoByGan(2, getZaoByZhi(2, "几人几丙")); + } + + /** + * 获取几人几锄 + * + * @return 几人几锄 + */ + public String getRenChu() { + return getZaoByGan(3, getZaoByZhi(2, "几人几锄")); } /** @@ -292,6 +430,154 @@ public class LunarYear { return YUN[((year + 2696) / 20) % 9] + "运"; } + /** + * 获取九星 + * + * @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) { + offset = 9; + } + return NineStar.fromIndex(offset - 1); + } + + /** + * 获取喜神方位 + * + * @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()); + } + + /** + * 获取福神方位(默认流派:2) + * + * @return 福神方位,如艮 + */ + public String getPositionFu() { + return getPositionFu(2); + } + + /** + * 获取福神方位 + * + * @param sect 流派,1或2 + * @return 福神方位,如艮 + */ + public String getPositionFu(int sect) { + return (1 == sect ? LunarUtil.POSITION_FU : LunarUtil.POSITION_FU_2)[ganIndex + 1]; + } + + /** + * 获取福神方位描述(默认流派:2) + * + * @return 福神方位描述,如东北 + */ + public String getPositionFuDesc() { + return getPositionFuDesc(2); + } + + /** + * 获取福神方位描述 + * + * @param sect 流派,1或2 + * @return 福神方位描述,如东北 + */ + public String getPositionFuDesc(int sect) { + return LunarUtil.POSITION_DESC.get(getPositionFu(sect)); + } + + /** + * 获取财神方位 + * + * @return 财神方位,如艮 + */ + public String getPositionCai() { + return LunarUtil.POSITION_CAI[ganIndex + 1]; + } + + /** + * 获取财神方位描述 + * + * @return 财神方位描述,如东北 + */ + public String getPositionCaiDesc() { + return LunarUtil.POSITION_DESC.get(getPositionCai()); + } + + /** + * 获取太岁方位 + * + * @return 太岁方位,如艮 + */ + public String getPositionTaiSui() { + return LunarUtil.POSITION_TAI_SUI_YEAR[zhiIndex]; + } + + /** + * 获取太岁方位描述 + * + * @return 太岁方位描述,如东北 + */ + public String getPositionTaiSuiDesc() { + return LunarUtil.POSITION_DESC.get(getPositionTaiSui()); + } + @Override public String toString() { return year + ""; diff --git a/src/main/java/com/nlf/calendar/NineStar.java b/src/main/java/com/nlf/calendar/NineStar.java index 1715ca0..0a106c9 100644 --- a/src/main/java/com/nlf/calendar/NineStar.java +++ b/src/main/java/com/nlf/calendar/NineStar.java @@ -5,198 +5,250 @@ import com.nlf.calendar.util.LunarUtil; /** * 九星 *

玄空九星、奇门九星都来源于北斗九星,九数、七色、五行、后天八卦方位都是相通的。

+ * * @author 6tail */ public class NineStar { - /** 九数 */ - public static final String[] NUMBER = {"一","二","三","四","五","六","七","八","九"}; + /** + * 九数 + */ + public static final String[] NUMBER = {"一", "二", "三", "四", "五", "六", "七", "八", "九"}; - /** 七色 */ - public static final String[] COLOR = {"白","黒","碧","绿","黄","白","赤","白","紫"}; + /** + * 七色 + */ + public static final String[] COLOR = {"白", "黒", "碧", "绿", "黄", "白", "赤", "白", "紫"}; - /** 五行 */ - public static final String[] WU_XING = {"水","土","木","木","土","金","金","土","火"}; + /** + * 五行 + */ + public static final String[] WU_XING = {"水", "土", "木", "木", "土", "金", "金", "土", "火"}; - /** 后天八卦方位 */ - public static final String[] POSITION = {"坎","坤","震","巽","中","乾","兑","艮","离"}; + /** + * 后天八卦方位 + */ + public static final String[] POSITION = {"坎", "坤", "震", "巽", "中", "乾", "兑", "艮", "离"}; - /** 北斗九星 */ - public static final String[] NAME_BEI_DOU = {"天枢","天璇","天玑","天权","玉衡","开阳","摇光","洞明","隐元"}; + /** + * 北斗九星 + */ + public static final String[] NAME_BEI_DOU = {"天枢", "天璇", "天玑", "天权", "玉衡", "开阳", "摇光", "洞明", "隐元"}; - /** 玄空九星(玄空风水) */ - public static final String[] NAME_XUAN_KONG = {"贪狼","巨门","禄存","文曲","廉贞","武曲","破军","左辅","右弼"}; + /** + * 玄空九星(玄空风水) + */ + public static final String[] NAME_XUAN_KONG = {"贪狼", "巨门", "禄存", "文曲", "廉贞", "武曲", "破军", "左辅", "右弼"}; - /** 奇门九星(奇门遁甲,也称天盘九星) */ - public static final String[] NAME_QI_MEN = {"天蓬","天芮","天冲","天辅","天禽","天心","天柱","天任","天英"}; + /** + * 奇门九星(奇门遁甲,也称天盘九星) + */ + public static final String[] NAME_QI_MEN = {"天蓬", "天芮", "天冲", "天辅", "天禽", "天心", "天柱", "天任", "天英"}; - /** 八门(奇门遁甲) */ - public static final String[] BA_MEN_QI_MEN = {"休","死","伤","杜","","开","惊","生","景"}; + /** + * 八门(奇门遁甲) + */ + public static final String[] BA_MEN_QI_MEN = {"休", "死", "伤", "杜", "", "开", "惊", "生", "景"}; - /** 太乙九神(太乙神数) */ - public static final String[] NAME_TAI_YI = {"太乙","摄提","轩辕","招摇","天符","青龙","咸池","太阴","天乙"}; + /** + * 太乙九神(太乙神数) + */ + public static final String[] NAME_TAI_YI = {"太乙", "摄提", "轩辕", "招摇", "天符", "青龙", "咸池", "太阴", "天乙"}; - /** 太乙九神对应类型 */ - public static final String[] TYPE_TAI_YI = {"吉神","凶神","安神","安神","凶神","吉神","凶神","吉神","吉神"}; + /** + * 太乙九神对应类型 + */ + public static final String[] TYPE_TAI_YI = {"吉神", "凶神", "安神", "安神", "凶神", "吉神", "凶神", "吉神", "吉神"}; - /** 太乙九神歌诀(太乙神数) */ - public static final String[] SONG_TAI_YI = {"门中太乙明,星官号贪狼,赌彩财喜旺,婚姻大吉昌,出入无阻挡,参谒见贤良,此行三五里,黑衣别阴阳。","门前见摄提,百事必忧疑,相生犹自可,相克祸必临,死门并相会,老妇哭悲啼,求谋并吉事,尽皆不相宜,只可藏隐遁,若动伤身疾。","出入会轩辕,凡事必缠牵,相生全不美,相克更忧煎,远行多不利,博彩尽输钱,九天玄女法,句句不虚言。","招摇号木星,当之事莫行,相克行人阻,阴人口舌迎,梦寐多惊惧,屋响斧自鸣,阴阳消息理,万法弗违情。","五鬼为天符,当门阴女谋,相克无好事,行路阻中途,走失难寻觅,道逢有尼姑,此星当门值,万事有灾除。","神光跃青龙,财气喜重重,投入有酒食,赌彩最兴隆,更逢相生旺,休言克破凶,见贵安营寨,万事总吉同。","吾将为咸池,当之尽不宜,出入多不利,相克有灾情,赌彩全输尽,求财空手回,仙人真妙语,愚人莫与知,动用虚惊退,反复逆风吹。","坐临太阴星,百祸不相侵,求谋悉成就,知交有觅寻,回风归来路,恐有殃伏起,密语中记取,慎乎莫轻行。","迎来天乙星,相逢百事兴,运用和合庆,茶酒喜相迎,求谋并嫁娶,好合有天成,祸福如神验,吉凶甚分明。"}; + /** + * 太乙九神歌诀(太乙神数) + */ + public static final String[] SONG_TAI_YI = {"门中太乙明,星官号贪狼,赌彩财喜旺,婚姻大吉昌,出入无阻挡,参谒见贤良,此行三五里,黑衣别阴阳。", "门前见摄提,百事必忧疑,相生犹自可,相克祸必临,死门并相会,老妇哭悲啼,求谋并吉事,尽皆不相宜,只可藏隐遁,若动伤身疾。", "出入会轩辕,凡事必缠牵,相生全不美,相克更忧煎,远行多不利,博彩尽输钱,九天玄女法,句句不虚言。", "招摇号木星,当之事莫行,相克行人阻,阴人口舌迎,梦寐多惊惧,屋响斧自鸣,阴阳消息理,万法弗违情。", "五鬼为天符,当门阴女谋,相克无好事,行路阻中途,走失难寻觅,道逢有尼姑,此星当门值,万事有灾除。", "神光跃青龙,财气喜重重,投入有酒食,赌彩最兴隆,更逢相生旺,休言克破凶,见贵安营寨,万事总吉同。", "吾将为咸池,当之尽不宜,出入多不利,相克有灾情,赌彩全输尽,求财空手回,仙人真妙语,愚人莫与知,动用虚惊退,反复逆风吹。", "坐临太阴星,百祸不相侵,求谋悉成就,知交有觅寻,回风归来路,恐有殃伏起,密语中记取,慎乎莫轻行。", "迎来天乙星,相逢百事兴,运用和合庆,茶酒喜相迎,求谋并嫁娶,好合有天成,祸福如神验,吉凶甚分明。"}; - /** 吉凶(玄空风水) */ - public static final String[] LUCK_XUAN_KONG = {"吉","凶","凶","吉","凶","吉","凶","吉","吉"}; + /** + * 吉凶(玄空风水) + */ + public static final String[] LUCK_XUAN_KONG = {"吉", "凶", "凶", "吉", "凶", "吉", "凶", "吉", "吉"}; - /** 吉凶(奇门遁甲) */ - public static final String[] LUCK_QI_MEN = {"大凶","大凶","小吉","大吉","大吉","大吉","小凶","小吉","小凶"}; + /** + * 吉凶(奇门遁甲) + */ + public static final String[] LUCK_QI_MEN = {"大凶", "大凶", "小吉", "大吉", "大吉", "大吉", "小凶", "小吉", "小凶"}; - /** 阴阳(奇门遁甲) */ - public static final String[] YIN_YANG_QI_MEN = {"阳","阴","阳","阳","阳","阴","阴","阳","阴"}; + /** + * 阴阳(奇门遁甲) + */ + public static final String[] YIN_YANG_QI_MEN = {"阳", "阴", "阳", "阳", "阳", "阴", "阴", "阳", "阴"}; - /** 序号,0到8 */ + /** + * 序号,0到8 + */ protected int index; public NineStar(int index) { this.index = index; } + public static NineStar fromIndex(int index) { + return new NineStar(index); + } + /** * 获取九数 + * * @return 九数 */ - public String getNumber(){ + public String getNumber() { return NUMBER[index]; } /** * 获取七色 + * * @return 七色 */ - public String getColor(){ + public String getColor() { return COLOR[index]; } /** * 获取五行 + * * @return 五行 */ - public String getWuXing(){ + public String getWuXing() { return WU_XING[index]; } /** * 获取方位 + * * @return 方位 */ - public String getPosition(){ + public String getPosition() { return POSITION[index]; } /** * 获取方位描述 + * * @return 方位描述 */ - public String getPositionDesc(){ + public String getPositionDesc() { return LunarUtil.POSITION_DESC.get(getPosition()); } /** * 获取玄空九星名称 + * * @return 玄空九星名称 */ - public String getNameInXuanKong(){ + public String getNameInXuanKong() { return NAME_XUAN_KONG[index]; } /** * 获取北斗九星名称 + * * @return 北斗九星名称 */ - public String getNameInBeiDou(){ + public String getNameInBeiDou() { return NAME_BEI_DOU[index]; } /** * 获取奇门九星名称 + * * @return 奇门九星名称 */ - public String getNameInQiMen(){ + public String getNameInQiMen() { return NAME_QI_MEN[index]; } /** * 获取太乙九神名称 + * * @return 太乙九神名称 */ - public String getNameInTaiYi(){ + public String getNameInTaiYi() { return NAME_TAI_YI[index]; } /** * 获取奇门九星吉凶 + * * @return 大吉/小吉/大凶/小凶 */ - public String getLuckInQiMen(){ + public String getLuckInQiMen() { return LUCK_QI_MEN[index]; } /** * 获取玄空九星吉凶 + * * @return 吉/凶 */ - public String getLuckInXuanKong(){ + public String getLuckInXuanKong() { return LUCK_XUAN_KONG[index]; } /** * 获取奇门九星阴阳 + * * @return 阴/阳 */ - public String getYinYangInQiMen(){ + public String getYinYangInQiMen() { return YIN_YANG_QI_MEN[index]; } /** * 获取太乙九神类型 + * * @return 吉神/凶神/安神 */ - public String getTypeInTaiYi(){ + public String getTypeInTaiYi() { return TYPE_TAI_YI[index]; } /** * 获取八门(奇门遁甲) + * * @return 八门 */ - public String getBaMenInQiMen(){ + public String getBaMenInQiMen() { return BA_MEN_QI_MEN[index]; } /** * 获取太乙九神歌诀 + * * @return 太乙九神歌诀 */ - public String getSongInTaiYi(){ + public String getSongInTaiYi() { return SONG_TAI_YI[index]; } /** * 获取九星序号,从0开始 + * * @return 序号 */ - public int getIndex(){ + public int getIndex() { return index; } @Override - public String toString(){ - return getNumber()+getColor()+getWuXing()+getNameInBeiDou(); + public String toString() { + return getNumber() + getColor() + getWuXing() + getNameInBeiDou(); } /** * 获取详细描述 + * * @return 详细描述 */ - public String toFullString(){ + public String toFullString() { StringBuilder s = new StringBuilder(); s.append(getNumber()); s.append(getColor()); @@ -215,7 +267,7 @@ public class NineStar { s.append(getNameInQiMen()); s.append(" "); s.append(getLuckInQiMen()); - if(getBaMenInQiMen().length()>0) { + if (getBaMenInQiMen().length() > 0) { s.append(" "); s.append(getBaMenInQiMen()); s.append("门"); diff --git a/src/main/java/com/nlf/calendar/Solar.java b/src/main/java/com/nlf/calendar/Solar.java index 943c3be..0f9061c 100644 --- a/src/main/java/com/nlf/calendar/Solar.java +++ b/src/main/java/com/nlf/calendar/Solar.java @@ -278,7 +278,7 @@ public class Solar { if (offsetYear < 0) { offsetYear = offsetYear + 60; } - int startYear = today.getYear() - offsetYear; + int startYear = lunar.getYear() - offsetYear; int hour = 0; String timeZhi = timeGanZhi.substring(1); for (int i = 0, j = LunarUtil.ZHI.length; i < j; i++) { diff --git a/src/main/java/com/nlf/calendar/Tao.java b/src/main/java/com/nlf/calendar/Tao.java index e042b78..6b4978f 100644 --- a/src/main/java/com/nlf/calendar/Tao.java +++ b/src/main/java/com/nlf/calendar/Tao.java @@ -176,6 +176,35 @@ public class Tao { return isDayMingWu() || isDayAnWu(); } + /** + * 是否天赦日 + * + * @return true/false + */ + public boolean isDayTianShe() { + boolean ret = false; + String mz = lunar.getMonthZhi(); + String dgz = lunar.getDayInGanZhi(); + if ("寅卯辰".contains(mz)) { + if ("戊寅".equals(dgz)) { + ret = true; + } + } else if ("巳午未".contains(mz)) { + if ("甲午".equals(dgz)) { + ret = true; + } + } else if ("申酉戌".contains(mz)) { + if ("戊申".equals(dgz)) { + ret = true; + } + } else if ("亥子丑".contains(mz)) { + if ("甲子".equals(dgz)) { + ret = true; + } + } + return ret; + } + @Override public String toString() { return String.format("%s年%s月%s", getYearInChinese(), getMonthInChinese(), getDayInChinese()); diff --git a/src/main/java/com/nlf/calendar/util/LunarUtil.java b/src/main/java/com/nlf/calendar/util/LunarUtil.java index a04f889..af53544 100644 --- a/src/main/java/com/nlf/calendar/util/LunarUtil.java +++ b/src/main/java/com/nlf/calendar/util/LunarUtil.java @@ -35,6 +35,12 @@ public class LunarUtil{ public static final String[] POSITION_FU_2 = {"","坎","坤","乾","巽","艮","坎","坤","乾","巽","艮"}; /** 财神方位,《财神方位歌》:甲乙东北是财神,丙丁向在西南寻,戊己正北坐方位, 庚辛正东去安身,壬癸原来正南坐,便是财神方位真。 */ public static final String[] POSITION_CAI = {"","艮","艮","坤","坤","坎","坎","震","震","离","离"}; + /** 年太岁方位 */ + public static final String[] POSITION_TAI_SUI_YEAR = {"坎","艮","艮","震","巽","巽","离","坤","坤","兑","坎","坎"}; + /** 天干方位 */ + public static final String[] POSITION_GAN = {"震","震","离","离","中","中","兑","兑","坎","坎"}; + /** 地支方位 */ + public static final String[] POSITION_ZHI = {"坎","中","震","震","中","离","离","中","兑","兑","中","坎"}; /** 逐日胎神方位 */ public static final String[] POSITION_TAI_DAY = {"占门碓 外东南","碓磨厕 外东南","厨灶炉 外正南","仓库门 外正南","房床栖 外正南","占门床 外正南","占碓磨 外正南","厕灶厨 外西南","仓库炉 外西南","房床门 外西南","门碓栖 外西南","碓磨床 外西南","厨灶碓 外西南","仓库厕 外正西","房床炉 外正西","占大门 外正西","碓磨栖 外正西","厨房床 外正西","仓库碓 外西北","房床厕 外西北","占门炉 外西北","门碓磨 外西北","厨灶栖 外西北","仓库床 外西北","房床碓 外正北","占门厕 外正北","碓磨炉 外正北","厨灶门 外正北","仓库栖 外正北","占房床 房内北","占门碓 房内北","碓磨厕 房内北","厨灶炉 房内北","门仓库 房内北","床房栖 房内中","占门床 房内中","占碓磨 房内南","厨磨厕 房内南","仓库炉 房内南","房床门 房内西","门碓栖 房内东","碓磨床 房内东","厨灶碓 房内东","仓库厕 房内东","房床炉 房内中","占大门 外东北","碓磨栖 外东北","厨灶床 外东北","仓库碓 外东北","房床厕 外东北","占门炉 外东北","门碓磨 外正东","厨灶栖 外正东","仓库床 外正东","房床碓 外正东","占门厕 外正东","碓磨炉 外东南","厨灶门 外东南","仓库栖 外东南","占房床 外东南"}; /** 逐月胎神方位 */ @@ -1134,8 +1140,8 @@ public class LunarUtil{ } } if(matched) { - String ys = left.substring(left.indexOf(':') + 1); - ys = ys.substring(0, ys.indexOf(',')); + String ys = left.substring(left.indexOf(":") + 1); + ys = ys.substring(0, ys.indexOf(",")); for (int i = 0, j = ys.length(); i < j; i += 2) { String m = ys.substring(i, i + 2); l.add(YI_JI[Integer.parseInt(m,16)]); diff --git a/src/main/java/com/nlf/calendar/util/SolarUtil.java b/src/main/java/com/nlf/calendar/util/SolarUtil.java index 6d360ef..7e95882 100644 --- a/src/main/java/com/nlf/calendar/util/SolarUtil.java +++ b/src/main/java/com/nlf/calendar/util/SolarUtil.java @@ -146,6 +146,16 @@ public class SolarUtil { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } + /** + * 获取某年有多少天(平年365天,闰年366天) + * + * @param year 年 + * @return 天数 + */ + public static int getDaysOfYear(int year) { + return isLeapYear(year) ? 366 : 365; + } + /** * 获取某年某月有多少天 * @@ -154,6 +164,9 @@ public class SolarUtil { * @return 天数 */ public static int getDaysOfMonth(int year, int month) { + if (1582 == year && 10 == month) { + return 21; + } int m = month - 1; int d = DAYS_OF_MONTH[m]; //公历闰年2月多一天 @@ -163,6 +176,26 @@ public class SolarUtil { return d; } + /** + * 获取某天为当年的第几天 + * + * @param year 年 + * @param month 月 + * @param day 日 + * @return 第几天 + */ + public static int getDaysInYear(int year, int month, int day) { + int days = 0; + for (int i = 1; i < month; i++) { + days += getDaysOfMonth(year, i); + } + days += day; + if (1582 == year && 10 == month && day >= 15) { + days -= 10; + } + return days; + } + /** * 获取某年某月有多少周 *