1
0
mirror of synced 2026-10-13 10:06:12 +08:00

v1.1.2 新增临近节气;新增八字起运、大运、流年、小运、流月。

This commit is contained in:
6tail
2020-08-31 09:47:35 +08:00
9 changed files with 1009 additions and 110 deletions

View File

@@ -1,5 +1,6 @@
package com.nlf.calendar;
import com.nlf.calendar.eightchar.Yun;
import com.nlf.calendar.util.LunarUtil;
import java.util.ArrayList;
@@ -9,128 +10,146 @@ import java.util.Map;
/**
* 八字
*
* @author 6tail
*/
public class EightChar {
/** 月支,按正月起寅排列 */
private static final String[] MONTH_ZHI = {"","寅","卯","辰","巳","午","未","申","酉","戌","亥","子","丑"};
/** 长生十二神 */
public static final String[] CHANG_SHENG = {"长生","沐浴","冠带","临官","帝旺","衰","病","死","墓","绝","胎","养"};
/** 长生十二神日干偏移值,五阳干顺推,五阴干逆推 */
private static final Map<String,Integer> CHANG_SHENG_OFFSET = new HashMap<String, Integer>(){
/**
* 月支,按正月起寅排列
*/
private static final String[] MONTH_ZHI = {"", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑"};
/**
* 长生十二神
*/
public static final String[] CHANG_SHENG = {"长生", "沐浴", "冠带", "临官", "帝旺", "衰", "病", "死", "墓", "绝", "胎", "养"};
/**
* 长生十二神日干偏移值,五阳干顺推,五阴干逆推
*/
private static final Map<String, Integer> CHANG_SHENG_OFFSET = new HashMap<String, Integer>() {
private static final long serialVersionUID = 1;
{
//阳
put("甲",11);
put("丙",2);
put("戊",2);
put("庚",5);
put("壬",8);
put("甲", 11);
put("丙", 2);
put("戊", 2);
put("庚", 5);
put("壬", 8);
//阴
put("乙",6);
put("丁",9);
put("己",9);
put("辛",0);
put("癸",3);
put("乙", 6);
put("丁", 9);
put("己", 9);
put("辛", 0);
put("癸", 3);
}
};
/** 阴历 */
/**
* 阴历
*/
protected Lunar lunar;
public EightChar(Lunar lunar){
public EightChar(Lunar lunar) {
this.lunar = lunar;
}
public static EightChar fromLunar(Lunar lunar){
public static EightChar fromLunar(Lunar lunar) {
return new EightChar(lunar);
}
@Override
public String toString(){
return getYear()+" "+getMonth()+" "+getDay()+" "+getTime();
public String toString() {
return getYear() + " " + getMonth() + " " + getDay() + " " + getTime();
}
/**
* 获取年柱
*
* @return 年柱
*/
public String getYear(){
public String getYear() {
return lunar.getYearInGanZhiExact();
}
/**
* 获取年干
*
* @return 天干
*/
public String getYearGan(){
public String getYearGan() {
return lunar.getYearGanExact();
}
/**
* 获取年支
*
* @return 地支
*/
public String getYearZhi(){
public String getYearZhi() {
return lunar.getYearZhiExact();
}
/**
* 获取年柱地支藏干,由于藏干分主气、余气、杂气,所以返回结果可能为1到3个元素
*
* @return 天干
*/
public List<String> getYearHideGan(){
public List<String> getYearHideGan() {
return LunarUtil.ZHI_HIDE_GAN.get(getYearZhi());
}
/**
* 获取年柱五行
*
* @return 五行
*/
public String getYearWuXing(){
return LunarUtil.WU_XING_GAN.get(lunar.getYearGanExact())+LunarUtil.WU_XING_ZHI.get(lunar.getYearZhiExact());
public String getYearWuXing() {
return LunarUtil.WU_XING_GAN.get(lunar.getYearGanExact()) + LunarUtil.WU_XING_ZHI.get(lunar.getYearZhiExact());
}
/**
* 获取年柱纳音
*
* @return 纳音
*/
public String getYearNaYin(){
public String getYearNaYin() {
return LunarUtil.NAYIN.get(getYear());
}
/**
* 获取年柱天干十神
*
* @return 十神
*/
public String getYearShiShenGan(){
return LunarUtil.SHI_SHEN_GAN.get(getDayGan()+getYearGan());
public String getYearShiShenGan() {
return LunarUtil.SHI_SHEN_GAN.get(getDayGan() + getYearGan());
}
private List<String> getShiShenZhi(String zhi){
private List<String> getShiShenZhi(String zhi) {
List<String> hideGan = LunarUtil.ZHI_HIDE_GAN.get(zhi);
List<String> l = new ArrayList<String>(hideGan.size());
for(String gan:hideGan){
l.add(LunarUtil.SHI_SHEN_ZHI.get(getDayGan()+zhi+gan));
for (String gan : hideGan) {
l.add(LunarUtil.SHI_SHEN_ZHI.get(getDayGan() + zhi + gan));
}
return l;
}
/**
* 获取年柱地支十神,由于藏干分主气、余气、杂气,所以返回结果可能为1到3个元素
*
* @return 十神
*/
public List<String> getYearShiShenZhi(){
public List<String> getYearShiShenZhi() {
return getShiShenZhi(getYearZhi());
}
private String getDiShi(int zhiIndex){
private String getDiShi(int zhiIndex) {
int offset = CHANG_SHENG_OFFSET.get(getDayGan());
int index = offset + (lunar.getDayGanIndexExact()%2==0?zhiIndex:-zhiIndex);
if(index>=12){
int index = offset + (lunar.getDayGanIndexExact() % 2 == 0 ? zhiIndex : -zhiIndex);
if (index >= 12) {
index -= 12;
}
if(index<0){
if (index < 0) {
index += 12;
}
return CHANG_SHENG[index];
@@ -138,277 +157,308 @@ public class EightChar {
/**
* 获取年柱地势(长生十二神)
*
* @return 地势
*/
public String getYearDiShi(){
public String getYearDiShi() {
return getDiShi(lunar.getYearZhiIndexExact());
}
/**
* 获取月柱
*
* @return 月柱
*/
public String getMonth(){
public String getMonth() {
return lunar.getMonthInGanZhiExact();
}
/**
* 获取月干
*
* @return 天干
*/
public String getMonthGan(){
public String getMonthGan() {
return lunar.getMonthGanExact();
}
/**
* 获取月支
*
* @return 地支
*/
public String getMonthZhi(){
public String getMonthZhi() {
return lunar.getMonthZhiExact();
}
/**
* 获取月柱地支藏干,由于藏干分主气、余气、杂气,所以返回结果可能为1到3个元素
*
* @return 天干
*/
public List<String> getMonthHideGan(){
public List<String> getMonthHideGan() {
return LunarUtil.ZHI_HIDE_GAN.get(getMonthZhi());
}
/**
* 获取月柱五行
*
* @return 五行
*/
public String getMonthWuXing(){
return LunarUtil.WU_XING_GAN.get(lunar.getMonthGanExact())+LunarUtil.WU_XING_ZHI.get(lunar.getMonthZhiExact());
public String getMonthWuXing() {
return LunarUtil.WU_XING_GAN.get(lunar.getMonthGanExact()) + LunarUtil.WU_XING_ZHI.get(lunar.getMonthZhiExact());
}
/**
* 获取月柱纳音
*
* @return 纳音
*/
public String getMonthNaYin(){
public String getMonthNaYin() {
return LunarUtil.NAYIN.get(getMonth());
}
/**
* 获取月柱天干十神
*
* @return 十神
*/
public String getMonthShiShenGan(){
return LunarUtil.SHI_SHEN_GAN.get(getDayGan()+getMonthGan());
public String getMonthShiShenGan() {
return LunarUtil.SHI_SHEN_GAN.get(getDayGan() + getMonthGan());
}
/**
* 获取月柱地支十神,由于藏干分主气、余气、杂气,所以返回结果可能为1到3个元素
*
* @return 十神
*/
public List<String> getMonthShiShenZhi(){
public List<String> getMonthShiShenZhi() {
return getShiShenZhi(getMonthZhi());
}
/**
* 获取月柱地势(长生十二神)
*
* @return 地势
*/
public String getMonthDiShi(){
public String getMonthDiShi() {
return getDiShi(lunar.getMonthZhiIndexExact());
}
/**
* 获取日柱
*
* @return 日柱
*/
public String getDay(){
public String getDay() {
return lunar.getDayInGanZhiExact();
}
/**
* 获取日干
*
* @return 天干
*/
public String getDayGan(){
public String getDayGan() {
return lunar.getDayGanExact();
}
/**
* 获取日支
*
* @return 地支
*/
public String getDayZhi(){
public String getDayZhi() {
return lunar.getDayZhiExact();
}
/**
* 获取日柱地支藏干,由于藏干分主气、余气、杂气,所以返回结果可能为1到3个元素
*
* @return 天干
*/
public List<String> getDayHideGan(){
public List<String> getDayHideGan() {
return LunarUtil.ZHI_HIDE_GAN.get(getDayZhi());
}
/**
* 获取日柱五行
*
* @return 五行
*/
public String getDayWuXing(){
return LunarUtil.WU_XING_GAN.get(lunar.getDayGanExact())+LunarUtil.WU_XING_ZHI.get(lunar.getDayZhiExact());
public String getDayWuXing() {
return LunarUtil.WU_XING_GAN.get(lunar.getDayGanExact()) + LunarUtil.WU_XING_ZHI.get(lunar.getDayZhiExact());
}
/**
* 获取日柱纳音
*
* @return 纳音
*/
public String getDayNaYin(){
public String getDayNaYin() {
return LunarUtil.NAYIN.get(getDay());
}
/**
* 获取日柱天干十神,也称日元、日干
*
* @return 十神
*/
public String getDayShiShenGan(){
public String getDayShiShenGan() {
return "日主";
}
/**
* 获取日柱地支十神,由于藏干分主气、余气、杂气,所以返回结果可能为1到3个元素
*
* @return 十神
*/
public List<String> getDayShiShenZhi(){
public List<String> getDayShiShenZhi() {
return getShiShenZhi(getDayZhi());
}
/**
* 获取日柱地势(长生十二神)
*
* @return 地势
*/
public String getDayDiShi(){
public String getDayDiShi() {
return getDiShi(lunar.getDayZhiIndexExact());
}
/**
* 获取时柱
*
* @return 时柱
*/
public String getTime(){
public String getTime() {
return lunar.getTimeInGanZhi();
}
/**
* 获取时干
*
* @return 天干
*/
public String getTimeGan(){
public String getTimeGan() {
return lunar.getTimeGan();
}
/**
* 获取时支
*
* @return 地支
*/
public String getTimeZhi(){
public String getTimeZhi() {
return lunar.getTimeZhi();
}
/**
* 获取时柱地支藏干,由于藏干分主气、余气、杂气,所以返回结果可能为1到3个元素
*
* @return 天干
*/
public List<String> getTimeHideGan(){
public List<String> getTimeHideGan() {
return LunarUtil.ZHI_HIDE_GAN.get(getTimeZhi());
}
/**
* 获取时柱五行
*
* @return 五行
*/
public String getTimeWuXing(){
return LunarUtil.WU_XING_GAN.get(lunar.getTimeGan())+LunarUtil.WU_XING_ZHI.get(lunar.getTimeZhi());
public String getTimeWuXing() {
return LunarUtil.WU_XING_GAN.get(lunar.getTimeGan()) + LunarUtil.WU_XING_ZHI.get(lunar.getTimeZhi());
}
/**
* 获取时柱纳音
*
* @return 纳音
*/
public String getTimeNaYin(){
public String getTimeNaYin() {
return LunarUtil.NAYIN.get(getTime());
}
/**
* 获取时柱天干十神
*
* @return 十神
*/
public String getTimeShiShenGan(){
return LunarUtil.SHI_SHEN_GAN.get(getDayGan()+getTimeGan());
public String getTimeShiShenGan() {
return LunarUtil.SHI_SHEN_GAN.get(getDayGan() + getTimeGan());
}
/**
* 获取时柱地支十神,由于藏干分主气、余气、杂气,所以返回结果可能为1到3个元素
*
* @return 十神
*/
public List<String> getTimeShiShenZhi(){
public List<String> getTimeShiShenZhi() {
return getShiShenZhi(getTimeZhi());
}
/**
* 获取时柱地势(长生十二神)
*
* @return 地势
*/
public String getTimeDiShi(){
public String getTimeDiShi() {
return getDiShi(lunar.getTimeZhiIndex());
}
/**
* 获取胎元
*
* @return 胎元
*/
public String getTaiYuan(){
public String getTaiYuan() {
int ganIndex = lunar.getMonthGanIndexExact() + 1;
if(ganIndex>=10){
if (ganIndex >= 10) {
ganIndex -= 10;
}
int zhiIndex = lunar.getMonthZhiIndexExact() + 3;
if(zhiIndex>=12){
if (zhiIndex >= 12) {
zhiIndex -= 12;
}
return LunarUtil.GAN[ganIndex+1]+LunarUtil.ZHI[zhiIndex+1];
return LunarUtil.GAN[ganIndex + 1] + LunarUtil.ZHI[zhiIndex + 1];
}
/**
* 获取胎元纳音
*
* @return 纳音
*/
public String getTaiYuanNaYin(){
public String getTaiYuanNaYin() {
return LunarUtil.NAYIN.get(getTaiYuan());
}
/**
* 获取命宫
*
* @return 命宫
*/
public String getMingGong(){
public String getMingGong() {
int monthZhiIndex = 0;
int timeZhiIndex = 0;
for(int i=0,j=MONTH_ZHI.length;i<j;i++){
for (int i = 0, j = MONTH_ZHI.length; i < j; i++) {
String zhi = MONTH_ZHI[i];
if(lunar.getMonthZhiExact().equals(zhi)){
if (lunar.getMonthZhiExact().equals(zhi)) {
monthZhiIndex = i;
}
if(lunar.getTimeZhi().equals(zhi)){
if (lunar.getTimeZhi().equals(zhi)) {
timeZhiIndex = i;
}
}
int zhiIndex = 26 - (monthZhiIndex+timeZhiIndex);
if(zhiIndex>12){
int zhiIndex = 26 - (monthZhiIndex + timeZhiIndex);
if (zhiIndex > 12) {
zhiIndex -= 12;
}
int jiaZiIndex = LunarUtil.getJiaZiIndex(lunar.getMonthInGanZhiExact()) - (monthZhiIndex-zhiIndex);
if(jiaZiIndex>=60){
int jiaZiIndex = LunarUtil.getJiaZiIndex(lunar.getMonthInGanZhiExact()) - (monthZhiIndex - zhiIndex);
if (jiaZiIndex >= 60) {
jiaZiIndex -= 60;
}
if(jiaZiIndex<0){
if (jiaZiIndex < 0) {
jiaZiIndex += 60;
}
return LunarUtil.JIA_ZI[jiaZiIndex];
@@ -416,34 +466,36 @@ public class EightChar {
/**
* 获取命宫纳音
*
* @return 纳音
*/
public String getMingGongNaYin(){
public String getMingGongNaYin() {
return LunarUtil.NAYIN.get(getMingGong());
}
/**
* 获取身宫
*
* @return 身宫
*/
public String getShenGong(){
public String getShenGong() {
int monthZhiIndex = 0;
int timeZhiIndex = 0;
for(int i=0,j=MONTH_ZHI.length;i<j;i++){
for (int i = 0, j = MONTH_ZHI.length; i < j; i++) {
String zhi = MONTH_ZHI[i];
if(lunar.getMonthZhiExact().equals(zhi)){
if (lunar.getMonthZhiExact().equals(zhi)) {
monthZhiIndex = i;
}
if(lunar.getTimeZhi().equals(zhi)){
if (lunar.getTimeZhi().equals(zhi)) {
timeZhiIndex = i;
}
}
int zhiIndex = (2 + (monthZhiIndex+timeZhiIndex))%12;
int jiaZiIndex = LunarUtil.getJiaZiIndex(lunar.getMonthInGanZhiExact()) - (monthZhiIndex-zhiIndex);
if(jiaZiIndex>=60){
int zhiIndex = (2 + (monthZhiIndex + timeZhiIndex)) % 12;
int jiaZiIndex = LunarUtil.getJiaZiIndex(lunar.getMonthInGanZhiExact()) - (monthZhiIndex - zhiIndex);
if (jiaZiIndex >= 60) {
jiaZiIndex -= 60;
}
if(jiaZiIndex<0){
if (jiaZiIndex < 0) {
jiaZiIndex += 60;
}
return LunarUtil.JIA_ZI[jiaZiIndex];
@@ -451,10 +503,26 @@ public class EightChar {
/**
* 获取身宫纳音
*
* @return 纳音
*/
public String getShenGongNaYin(){
public String getShenGongNaYin() {
return LunarUtil.NAYIN.get(getShenGong());
}
public Lunar getLunar() {
return lunar;
}
/**
* 获取运
*
* @param gender 性别:1男,0女
* @return 运
*/
public Yun getYun(int gender) {
return new Yun(this, gender);
}
}

View File

@@ -0,0 +1,56 @@
package com.nlf.calendar;
/**
* 节气
*
* @author 6tail
*/
public class JieQi {
/** 名称 */
private String name;
/** 阳历日期 */
private Solar solar;
public JieQi() {
}
public JieQi(String name, Solar solar) {
this.name = name;
this.solar = solar;
}
/**
* 获取名称
* @return 名称
*/
public String getName() {
return name;
}
/**
* 设置名称
* @param name 名称
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取阳历日期
* @return 阳历日期
*/
public Solar getSolar() {
return solar;
}
/**
* 设置阳历日期
* @param solar 阳历日期
*/
public void setSolar(Solar solar) {
this.solar = solar;
}
}

View File

@@ -1915,6 +1915,89 @@ public class Lunar{
return jieQi;
}
/**
* 获取下一节(顺推的第一个节)
* @return 节气
*/
public JieQi getNextJie(){
return getNearJieQi(true,LunarUtil.JIE);
}
/**
* 获取上一节(逆推的第一个节)
* @return 节气
*/
public JieQi getPrevJie(){
return getNearJieQi(false,LunarUtil.JIE);
}
/**
* 获取下一节气(顺推的第一个节气)
* @return 节气
*/
public JieQi getNextJieQi(){
return getNearJieQi(true,null);
}
/**
* 获取上一节气(逆推的第一个节气)
* @return 节气
*/
public JieQi getPrevJieQi(){
return getNearJieQi(false,null);
}
/**
* 获取最近的节气,如果未找到匹配的,返回null
* @param forward 是否顺推,true为顺推,false为逆推
* @param conditions 过滤条件,如果设置过滤条件,仅返回匹配该名称的
* @return 节气
*/
protected JieQi getNearJieQi(boolean forward, String[] conditions){
String name = null;
Solar near = null;
Set<String> filters = new HashSet<String>();
if(null!=conditions) {
Collections.addAll(filters, conditions);
}
boolean filter = !filters.isEmpty();
String today = solar.toYmdHms();
for(Map.Entry<String,Solar> entry:jieQi.entrySet()){
String jq = entry.getKey();
if("DONG_ZHI".equals(jq)){
jq = "冬至";
}
if(filter){
if(!filters.contains(jq)){
continue;
}
}
Solar solar = entry.getValue();
String day = solar.toYmdHms();
if(forward){
if(day.compareTo(today)<0){
continue;
}
if(null==near || day.compareTo(near.toYmdHms())<0){
name = jq;
near = solar;
}
}else{
if(day.compareTo(today)>0){
continue;
}
if(null==near || day.compareTo(near.toYmdHms())>0) {
name = jq;
near = solar;
}
}
}
if(null==near){
return null;
}
return new JieQi(name, near);
}
public String toFullString(){
StringBuilder s = new StringBuilder();
s.append(toString());

View File

@@ -0,0 +1,135 @@
package com.nlf.calendar.eightchar;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.util.LunarUtil;
/**
* 大运
*
* @author 6tail
*/
public class DaYun {
/**
* 开始年(含)
*/
private int startYear;
/**
* 结束年(含)
*/
private int endYear;
/**
* 开始年龄(含)
*/
private int startAge;
/**
* 结束年龄(含)
*/
private int endAge;
/**
* 序数,0-9
*/
private int index;
/**
* 运
*/
private Yun yun;
private Lunar lunar;
public DaYun(Yun yun, int index) {
this.yun = yun;
this.lunar = yun.getLunar();
this.index = index;
int year = yun.getStartSolar().getYear();
if (index < 1) {
this.startYear = lunar.getSolar().getYear();
this.startAge = 1;
this.endYear = year - 1;
this.endAge = yun.getStartYear();
} else {
int add = (index - 1) * 10;
this.startYear = year + add;
this.startAge = yun.getStartYear() + add + 1;
this.endYear = this.startYear + 9;
this.endAge = this.startAge + 9;
}
}
public int getStartYear() {
return startYear;
}
public int getEndYear() {
return endYear;
}
public int getStartAge() {
return startAge;
}
public int getEndAge() {
return endAge;
}
public int getIndex() {
return index;
}
public Lunar getLunar() {
return lunar;
}
/**
* 获取干支
*
* @return 干支
*/
public String getGanZhi() {
if (index < 1) {
return "";
}
int offset = LunarUtil.getJiaZiIndex(lunar.getMonthInGanZhiExact());
offset += yun.isForward() ? index : -index;
int size = LunarUtil.JIA_ZI.length;
if (offset >= size) {
offset -= size;
}
if (offset < 0) {
offset += size;
}
return LunarUtil.JIA_ZI[offset];
}
/**
* 获取流年
*
* @return 流年
*/
public LiuNian[] getLiuNian() {
int n = 10;
if (index < 1) {
n = endYear-startYear+1;
}
LiuNian[] l = new LiuNian[n];
for (int i = 0; i < n; i++) {
l[i] = new LiuNian(this, i);
}
return l;
}
/**
* 获取小运
*
* @return 小运
*/
public XiaoYun[] getXiaoYun() {
int n = 10;
if (index < 1) {
n = endYear-startYear+1;
}
XiaoYun[] l = new XiaoYun[n];
for (int i = 0; i < n; i++) {
l[i] = new XiaoYun(this, i, yun.isForward());
}
return l;
}
}

View File

@@ -0,0 +1,72 @@
package com.nlf.calendar.eightchar;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.util.LunarUtil;
/**
* 流年
*
* @author 6tail
*/
public class LiuNian {
/**
* 序数,0-9
*/
private int index;
/**
* 大运
*/
private DaYun daYun;
/**
* 年
*/
private int year;
/**
* 年龄
*/
private int age;
private Lunar lunar;
public LiuNian(DaYun daYun, int index) {
this.daYun = daYun;
this.lunar = daYun.getLunar();
this.index = index;
this.year = daYun.getStartYear() + index;
this.age = daYun.getStartAge() + index;
}
public int getIndex() {
return index;
}
public int getYear() {
return year;
}
public int getAge() {
return age;
}
/**
* 获取干支
*
* @return 干支
*/
public String getGanZhi() {
int offset = LunarUtil.getJiaZiIndex(lunar.getYearInGanZhiExact()) + this.index;
if (daYun.getIndex() > 0) {
offset += daYun.getStartAge() - 1;
}
offset %= LunarUtil.JIA_ZI.length;
return LunarUtil.JIA_ZI[offset];
}
public LiuYue[] getLiuYue() {
int n = 12;
LiuYue[] l = new LiuYue[n];
for (int i = 0; i < n; i++) {
l[i] = new LiuYue(this, i);
}
return l;
}
}

View File

@@ -0,0 +1,64 @@
package com.nlf.calendar.eightchar;
import com.nlf.calendar.util.LunarUtil;
/**
* 流月
*
* @author 6tail
*/
public class LiuYue {
/**
* 序数,0-9
*/
private int index;
private LiuNian liuNian;
public LiuYue(LiuNian liuNian, int index) {
this.liuNian = liuNian;
this.index = index;
}
public int getIndex() {
return index;
}
/**
* 获取中文的月
*
* @return 中文月,如正
*/
public String getMonthInChinese() {
return LunarUtil.MONTH[index + 1];
}
/**
* 获取干支
* <p>
* 《五虎遁》
* 甲己之年丙作首,
* 乙庚之年戊为头,
* 丙辛之年寻庚上,
* 丁壬壬寅顺水流,
* 若问戊癸何处走,
* 甲寅之上好追求。
*
* @return 干支
*/
public String getGanZhi() {
int offset = 0;
String yearGan = liuNian.getGanZhi().substring(0, 1);
if ("甲".equals(yearGan) || "己".equals(yearGan)) {
offset = 2;
} else if ("乙".equals(yearGan) || "庚".equals(yearGan)) {
offset = 4;
} else if ("丙".equals(yearGan) || "辛".equals(yearGan)) {
offset = 6;
} else if ("丁".equals(yearGan) || "壬".equals(yearGan)) {
offset = 8;
}
String gan = LunarUtil.GAN[(index + offset) % 10 + 1];
String zhi = LunarUtil.ZHI[(index + LunarUtil.BASE_MONTH_ZHI_INDEX) % 12 + 1];
return gan + zhi;
}
}

View File

@@ -0,0 +1,74 @@
package com.nlf.calendar.eightchar;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.util.LunarUtil;
/**
* 小运
*
* @author 6tail
*/
public class XiaoYun {
/**
* 序数,0-9
*/
private int index;
/**
* 大运
*/
private DaYun daYun;
/**
* 年
*/
private int year;
/**
* 年龄
*/
private int age;
/**
* 是否顺推
*/
private boolean forward;
private Lunar lunar;
public XiaoYun(DaYun daYun, int index, boolean forward) {
this.daYun = daYun;
this.lunar = daYun.getLunar();
this.index = index;
this.year = daYun.getStartYear() + index;
this.age = daYun.getStartAge() + index;
this.forward = forward;
}
public int getIndex() {
return index;
}
public int getYear() {
return year;
}
public int getAge() {
return age;
}
/**
* 获取干支
*
* @return 干支
*/
public String getGanZhi() {
int offset = LunarUtil.getJiaZiIndex(lunar.getTimeInGanZhi());
int add = this.index + 1;
if (daYun.getIndex() > 0) {
add += daYun.getStartAge() - 1;
}
offset += forward ? add : -add;
int size = LunarUtil.JIA_ZI.length;
while (offset < 0) {
offset += size;
}
offset %= size;
return LunarUtil.JIA_ZI[offset];
}
}

View File

@@ -0,0 +1,162 @@
package com.nlf.calendar.eightchar;
import com.nlf.calendar.EightChar;
import com.nlf.calendar.JieQi;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import com.nlf.calendar.util.LunarUtil;
import java.util.Calendar;
/**
* 运
*
* @author 6tail
*/
public class Yun {
/**
* 性别(1男,0女)
*/
private int gender;
/**
* 起运年数
*/
private int startYear;
/**
* 起运月数
*/
private int startMonth;
/**
* 起运天数
*/
private int startDay;
/**
* 是否顺推
*/
private boolean forward;
private Lunar lunar;
public Yun(EightChar eightChar, int gender) {
this.lunar = eightChar.getLunar();
this.gender = gender;
// 阳
boolean yang = 0 == lunar.getYearGanIndexExact() % 2;
// 男
boolean man = 1 == gender;
forward = (yang && man) || (!yang && !man);
computeStart();
}
/**
* 起运计算
*/
private void computeStart() {
// 上节
JieQi prev = lunar.getPrevJie();
// 下节
JieQi next = lunar.getNextJie();
// 出生日期
Solar current = lunar.getSolar();
// 阳男阴女顺推,阴男阳女逆推
Solar start = forward ? current : prev.getSolar();
Solar end = forward ? next.getSolar() : current;
// 时辰差
int hourDiff = LunarUtil.getTimeZhiIndex(end.toYmdHms().substring(11, 16)) - LunarUtil.getTimeZhiIndex(start.toYmdHms().substring(11, 16));
Calendar endCalendar = Calendar.getInstance();
endCalendar.set(end.getYear(), end.getMonth() - 1, end.getDay(), 0, 0, 0);
endCalendar.set(Calendar.MILLISECOND, 0);
Calendar startCalendar = Calendar.getInstance();
startCalendar.set(start.getYear(), start.getMonth() - 1, start.getDay(), 0, 0, 0);
startCalendar.set(Calendar.MILLISECOND, 0);
// 天数差
int dayDiff = (int) ((endCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / (1000 * 3600 * 24));
if (hourDiff < 0) {
hourDiff += 12;
dayDiff--;
}
int monthDiff = hourDiff * 10 / 30;
int month = dayDiff * 4 + monthDiff;
int day = hourDiff * 10 - monthDiff * 30;
int year = month / 12;
month = month - year * 12;
this.startYear = year;
this.startMonth = month;
this.startDay = day;
}
/**
* 获取性别
*
* @return 性别(1男 , 0女)
*/
public int getGender() {
return gender;
}
/**
* 获取起运年数
*
* @return 起运年数
*/
public int getStartYear() {
return startYear;
}
/**
* 获取起运月数
*
* @return 起运月数
*/
public int getStartMonth() {
return startMonth;
}
/**
* 获取起运天数
*
* @return 起运天数
*/
public int getStartDay() {
return startDay;
}
/**
* 是否顺推
*
* @return true/false
*/
public boolean isForward() {
return forward;
}
public Lunar getLunar() {
return lunar;
}
/**
* 获取起运的阳历日期
*
* @return 阳历日期
*/
public Solar getStartSolar() {
Solar birth = lunar.getSolar();
Calendar c = Calendar.getInstance();
c.set(birth.getYear() + startYear, birth.getMonth() - 1 + startMonth, birth.getDay() + startDay, 0, 0, 0);
return Solar.fromCalendar(c);
}
/**
* 获取大运
*
* @return 大运
*/
public DaYun[] getDaYun() {
int n = 10;
DaYun[] l = new DaYun[n];
for (int i = 0; i < n; i++) {
l[i] = new DaYun(this, i);
}
return l;
}
}

View File

@@ -1,60 +1,64 @@
package sample;
import com.nlf.calendar.EightChar;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import com.nlf.calendar.eightchar.*;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
/**
* 八字测试
*
* @author 6tail
*/
public class BaZiTestNew {
@Test
public void test1(){
Solar solar = new Solar(2020,1,1,22,35,0);
public void test1() {
Solar solar = new Solar(2020, 1, 1, 22, 35, 0);
Lunar lunar = solar.getLunar();
//己亥 丙子 癸卯 癸亥
System.out.println(lunar.getEightChar());
}
@Test
public void test2(){
Solar solar = new Solar(2020,1,6,14,35,0);
public void test2() {
Solar solar = new Solar(2020, 1, 6, 14, 35, 0);
Lunar lunar = solar.getLunar();
//己亥, 丁丑, 戊申, 己未]
System.out.println(lunar.getEightChar());
}
@Test
public void test3(){
Solar solar = new Solar(2020,1,6,3,35,0);
public void test3() {
Solar solar = new Solar(2020, 1, 6, 3, 35, 0);
Lunar lunar = solar.getLunar();
//己亥, 丁丑, 戊辰, 癸亥]
System.out.println(lunar.getEightChar());
}
@Test
public void test4(){
Solar solar = new Solar(2020,1,26,21,41,0);
public void test4() {
Solar solar = new Solar(2020, 1, 26, 21, 41, 0);
Lunar lunar = solar.getLunar();
//己亥, 丙子, 戊申, 甲寅]
System.out.println(lunar.getEightChar());
}
@Test
public void test5(){
Solar solar = new Solar(2020,2,4,1,42,0);
public void test5() {
Solar solar = new Solar(2020, 2, 4, 1, 42, 0);
Lunar lunar = solar.getLunar();
//己亥, 丁丑, 丁丑, 辛丑]
System.out.println(lunar.getEightChar());
}
@Test
public void test6(){
Solar solar = new Solar(2020,2,5,21,43,0);
public void test6() {
Solar solar = new Solar(2020, 2, 5, 21, 43, 0);
Lunar lunar = solar.getLunar();
//庚子, 戊寅, 戊寅, 癸亥]
System.out.println(lunar.getEightChar());
@@ -70,8 +74,8 @@ public class BaZiTestNew {
}
@Test
public void test7(){
Solar solar = new Solar(2020,5,26,23,43,0);
public void test7() {
Solar solar = new Solar(2020, 5, 26, 23, 43, 0);
Lunar lunar = solar.getLunar();
//庚子, 辛巳, 庚午, 丙子]
System.out.println(lunar.getEightChar());
@@ -106,7 +110,7 @@ public class BaZiTestNew {
@Test
public void testBaziShiShenZhi() {
Solar solar = new Solar(2020,1,1,22,35,0);
Solar solar = new Solar(2020, 1, 1, 22, 35, 0);
Lunar lunar = solar.getLunar();
//己亥 丙子 癸卯 癸亥
System.out.println(lunar.getEightChar());
@@ -129,4 +133,185 @@ public class BaZiTestNew {
System.out.println(lunar.getEightChar().getTimeShiShenZhi());
}
/**
* 起运
*/
@Test
public void testQiYun() {
Solar solar = new Solar(1983, 2, 15, 20, 0, 0);
Lunar lunar = solar.getLunar();
EightChar bazi = lunar.getEightChar();
Yun yun = bazi.getYun(0);
Assert.assertEquals(6, yun.getStartYear());
Assert.assertEquals(2, yun.getStartMonth());
Assert.assertEquals(20, yun.getStartDay());
Assert.assertEquals("1989-05-05", yun.getStartSolar().toYmd());
solar = new Solar(2013, 7, 13, 16, 17, 0);
lunar = solar.getLunar();
bazi = lunar.getEightChar();
yun = bazi.getYun(0);
Assert.assertEquals(8, yun.getStartYear());
Assert.assertEquals(4, yun.getStartMonth());
Assert.assertEquals(0, yun.getStartDay());
Assert.assertEquals("2021-11-13", yun.getStartSolar().toYmd());
solar = new Solar(2020, 8, 18, 10, 0, 0);
lunar = solar.getLunar();
bazi = lunar.getEightChar();
yun = bazi.getYun(0);
Assert.assertEquals(3, yun.getStartYear());
Assert.assertEquals(8, yun.getStartMonth());
Assert.assertEquals(0, yun.getStartDay());
Assert.assertEquals("2024-04-18", yun.getStartSolar().toYmd());
solar = new Solar(1972, 6, 15, 0, 0, 0);
lunar = solar.getLunar();
bazi = lunar.getEightChar();
yun = bazi.getYun(1);
Assert.assertEquals(7, yun.getStartYear());
Assert.assertEquals(5, yun.getStartMonth());
Assert.assertEquals(10, yun.getStartDay());
Assert.assertEquals("1979-11-25", yun.getStartSolar().toYmd());
solar = new Solar(1968, 11, 22, 0, 0, 0);
lunar = solar.getLunar();
bazi = lunar.getEightChar();
yun = bazi.getYun(1);
Assert.assertEquals(5, yun.getStartYear());
Assert.assertEquals(1, yun.getStartMonth());
Assert.assertEquals(20, yun.getStartDay());
Assert.assertEquals("1974-01-11", yun.getStartSolar().toYmd());
solar = new Solar(1968, 11, 23, 0, 0, 0);
lunar = solar.getLunar();
bazi = lunar.getEightChar();
yun = bazi.getYun(1);
Assert.assertEquals(4, yun.getStartYear());
Assert.assertEquals(9, yun.getStartMonth());
Assert.assertEquals(20, yun.getStartDay());
Assert.assertEquals("1973-09-12", yun.getStartSolar().toYmd());
}
/**
* 大运
*/
@Test
public void testDaYun() {
int[] startYears = {1983, 1989, 1999, 2009, 2019, 2029, 2039, 2049, 2059, 2069};
int[] endYears = {1988, 1998, 2008, 2018, 2028, 2038, 2048, 2058, 2068, 2078};
int[] startAges = {1, 7, 17, 27, 37, 47, 57, 67, 77, 87};
int[] endAges = {6, 16, 26, 36, 46, 56, 66, 76, 86, 96};
String[] yearGanZhi = {"", "乙卯", "丙辰", "丁巳", "戊午", "己未", "庚申", "辛酉", "壬戌", "癸亥"};
Solar solar = new Solar(1983, 2, 15, 20, 0, 0);
Lunar lunar = solar.getLunar();
EightChar bazi = lunar.getEightChar();
Yun yun = bazi.getYun(0);
DaYun[] l = yun.getDaYun();
for (int i = 0, j = l.length; i < j; i++) {
DaYun daYun = l[i];
Assert.assertEquals(startYears[i], daYun.getStartYear());
Assert.assertEquals(endYears[i], daYun.getEndYear());
Assert.assertEquals(startAges[i], daYun.getStartAge());
Assert.assertEquals(endAges[i], daYun.getEndAge());
Assert.assertEquals(yearGanZhi[i], daYun.getGanZhi());
}
}
/**
* 流年
*/
@Test
public void testLiuNian() {
Solar solar = new Solar(1983, 2, 15, 20, 0, 0);
Lunar lunar = solar.getLunar();
EightChar bazi = lunar.getEightChar();
Yun yun = bazi.getYun(0);
DaYun[] daYun = yun.getDaYun();
int[] years = {1983, 1984, 1985, 1986, 1987, 1988};
int[] ages = {1, 2, 3, 4, 5, 6};
String[] ganZhi = {"癸亥", "甲子", "乙丑", "丙寅", "丁卯", "戊辰"};
LiuNian[] l = daYun[0].getLiuNian();
for (int i = 0, j = l.length; i < j; i++) {
LiuNian liuNian = l[i];
Assert.assertEquals(years[i], liuNian.getYear());
Assert.assertEquals(ages[i], liuNian.getAge());
Assert.assertEquals(ganZhi[i], liuNian.getGanZhi());
}
years = new int[]{2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038};
ages = new int[]{47, 48, 49, 50, 51, 52, 53, 54, 55, 56};
ganZhi = new String[]{"己酉", "庚戌", "辛亥", "壬子", "癸丑", "甲寅", "乙卯", "丙辰", "丁巳", "戊午"};
l = daYun[5].getLiuNian();
for (int i = 0, j = l.length; i < j; i++) {
LiuNian liuNian = l[i];
Assert.assertEquals(years[i], liuNian.getYear());
Assert.assertEquals(ages[i], liuNian.getAge());
Assert.assertEquals(years[i] + "年", ganZhi[i], liuNian.getGanZhi());
}
}
/**
* 小运
*/
@Test
public void testXiaoYun() {
Solar solar = new Solar(1983, 2, 15, 20, 0, 0);
Lunar lunar = solar.getLunar();
EightChar bazi = lunar.getEightChar();
Yun yun = bazi.getYun(0);
DaYun[] daYun = yun.getDaYun();
int[] years = {1983, 1984, 1985, 1986, 1987, 1988};
int[] ages = {1, 2, 3, 4, 5, 6};
String[] ganZhi = {"乙亥", "丙子", "丁丑", "戊寅", "己卯", "庚辰"};
XiaoYun[] l = daYun[0].getXiaoYun();
for (int i = 0, j = l.length; i < j; i++) {
XiaoYun xiaoYun = l[i];
Assert.assertEquals(years[i], xiaoYun.getYear());
Assert.assertEquals(ages[i], xiaoYun.getAge());
Assert.assertEquals(ganZhi[i], xiaoYun.getGanZhi());
}
years = new int[]{2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038};
ages = new int[]{47, 48, 49, 50, 51, 52, 53, 54, 55, 56};
ganZhi = new String[]{"辛酉", "壬戌", "癸亥", "甲子", "乙丑", "丙寅", "丁卯", "戊辰", "己巳", "庚午"};
l = daYun[5].getXiaoYun();
for (int i = 0, j = l.length; i < j; i++) {
XiaoYun xiaoYun = l[i];
Assert.assertEquals(years[i], xiaoYun.getYear());
Assert.assertEquals(ages[i], xiaoYun.getAge());
Assert.assertEquals(years[i] + "年", ganZhi[i], xiaoYun.getGanZhi());
}
}
/**
* 流月
*/
@Test
public void testLiuYue() {
Solar solar = new Solar(1983, 2, 15, 20, 0, 0);
Lunar lunar = solar.getLunar();
EightChar bazi = lunar.getEightChar();
Yun yun = bazi.getYun(0);
DaYun[] daYun = yun.getDaYun();
String[] ganZhi = {"甲寅", "乙卯", "丙辰", "丁巳", "戊午", "己未", "庚申", "辛酉", "壬戌", "癸亥", "甲子", "乙丑"};
LiuNian[] liuNian = daYun[0].getLiuNian();
LiuYue[] l = liuNian[0].getLiuYue();
for (int i = 0, j = l.length; i < j; i++) {
LiuYue liuYue = l[i];
Assert.assertEquals(ganZhi[i], liuYue.getGanZhi());
}
ganZhi = new String[]{"庚寅", "辛卯", "壬辰", "癸巳", "甲午", "乙未", "丙申", "丁酉", "戊戌", "己亥", "庚子", "辛丑"};
liuNian = daYun[4].getLiuNian();
l = liuNian[2].getLiuYue();
for (int i = 0, j = l.length; i < j; i++) {
LiuYue liuYue = l[i];
Assert.assertEquals(ganZhi[i], liuYue.getGanZhi());
}
}
}