八字分四柱,每柱2字,分别对应年、月、日、时
一、天干,地支
/** * 天干 * */ public enum TianGan { 甲(1, "甲"), 乙(2,"乙"), 丙(3, "丙"),丁(4, "丁"), 戊(5, "戊"),己(6, "己"), 庚(7, "庚"),辛(8, "辛"), 壬(9, "壬"),癸(10, "癸"); private int code; private String desc; TianGan(int code, String desc){ this.code = code; this.desc = desc; } public int getCode() { return code; } public String getDesc() { return desc; } public static TianGan getByCode(int code){ for (TianGan tg : values()){ if (tg.code == code)return tg; } return 甲; } }
/** * 地支 * * **/ public enum DiZhi { 子(1, "子", "23:00-01:00", "00:00-02:00", "鼠"), 丑(2, "丑", "01:00-03:00", "02:00-04:00", "牛"), 寅(3, "寅", "03:00-05:00", "04:00-06:00", "虎"), 卯(4, "卯", "05:00-07:00", "06:00-08:00", "兔"), 辰(5, "辰", "07:00-09:00", "08:00-10:00", "龙"), 巳(6, "巳", "09:00-11:00", "10:00-12:00", "蛇"), 午(7, "午", "11:00-13:00", "12:00-14:00", "马"), 未(8, "未", "13:00-15:00", "14:00-16:00", "羊"), 申(9, "申", "15:00-17:00", "16:00-18:00", "猴"), 酉(10, "酉", "17:00-19:00", "18:00-20:00", "鸡"), 戌(11, "戌", "19:00-21:00", "20:00-22:00", "狗"), 亥(12, "亥", "21:00-23:00", "22:00-00:00", "猪"); private int code; private String desc,shiChen, shiChenBeforeTang,shengXiao; DiZhi(int code, String desc, String shiChen, String shiChenBeforeTang, String shengXiao){ this.code = code; this.desc = desc; this.shiChen = shiChen; this.shiChenBeforeTang = shiChenBeforeTang; this.shengXiao = shengXiao; } public int getCode() { return code; } public String getDesc() { return desc; } public static DiZhi getByCode(int code){ for (DiZhi dz : values()){ if (code == dz.code)return dz; } return DiZhi.子; } /** * 获取时辰时间段 * * **/ public String getShiChen() { return shiChen; } /** * 获取唐前时辰时间段 * * **/ public String getShiChenBeforeTang() { return shiChenBeforeTang; } /** * 生肖 * * **/ public String getShengXiao() { return shengXiao; } }
public enum ShiChen { 早子(1, "早子", "23:00-00:00", "00:00-01:00"), 丑(2, "丑", "01:00-03:00", "02:00-04:00"), 寅(3, "寅", "03:00-05:00", "04:00-06:00"), 卯(4, "卯", "05:00-07:00", "06:00-08:00"), 辰(5, "辰", "07:00-09:00", "08:00-10:00"), 巳(6, "巳", "09:00-11:00", "10:00-12:00"), 午(7, "午", "11:00-13:00", "12:00-14:00"), 未(8, "未", "13:00-15:00", "14:00-16:00"), 申(9, "申", "15:00-17:00", "16:00-18:00"), 酉(10, "酉", "17:00-19:00", "18:00-20:00"), 戌(11, "戌", "19:00-21:00", "20:00-22:00"), 亥(12, "亥", "21:00-23:00", "22:00-00:00"), 晚子(13, "晚子", "00:00-01:00", "01:00-02:00"); private int code; private String desc,shiChen, shiChenBeforeTang; ShiChen(int code, String desc, String shiChen, String shiChenBeforeTang){ this.code = code; this.desc = desc; this.shiChen = shiChen; this.shiChenBeforeTang = shiChenBeforeTang; } public int getCode() { return code; } public String getDesc() { return desc; } public static ShiChen getByCode(int code){ for (ShiChen dz : values()){ if (code == dz.code)return dz; } return ShiChen.早子; } /** * 获取时辰时间段 * * **/ public String getShiChen() { return shiChen; } /** * 获取唐前时辰时间段 * * **/ public String getShiChenBeforeTang() { return shiChenBeforeTang; } }
二、八字计算
1、基础数据表
// 纪月 private static final String[] JI_YUE_TIAN_GAN = new String[]{ "甲、已","乙、庚","丙、辛","丁、壬","戊、癸" }; private static final String[][] JI_YUE = new String[][]{ {"丙寅","丁卯","戊辰","已巳","庚午","辛未","壬申","癸酉","甲戌","乙亥","丙子","丁丑"}, {"戊寅","已卯","庚辰","辛巳","壬午","癸未","甲申","乙酉","丙戌","丁亥","戊子","已丑"}, {"庚寅","辛卯","壬辰","癸巳","甲午","乙未","丙申","丁酉","戊戌","已亥","庚子","辛丑"}, {"壬寅","癸卯","甲辰","乙巳","丙午","丁未","戊申","已酉","庚戌","辛亥","壬子","癸丑"}, {"甲寅","乙卯","丙辰","丁巳","戊午","已未","庚申","辛酉","壬戌","癸亥","甲子","乙丑"} }; // 纪时 private static final String[][] JI_SHI = new String[][]{ {"甲子","乙丑","丙寅","丁卯","戊辰","已巳","庚午","辛未","壬申","癸酉","甲戌","乙亥"}, {"丙子","丁丑","戊寅","已卯","庚辰","辛巳","壬午","癸未","甲申","乙酉","丙戌","丁亥"}, {"戊子","已丑","庚寅","辛卯","壬辰","癸巳","甲午","乙未","丙申","丁酉","戊戌","已亥"}, {"庚子","辛丑","壬寅","癸卯","甲辰","乙巳","丙午","丁未","戊申","已酉","庚戌","辛亥"}, {"壬子","癸丑","甲寅","乙卯","丙辰","丁巳","戊午","已未","庚申","辛酉","壬戌","癸亥"} };
/** * 批八字 * @param year 公历年 * @param month 公历月 * @param day 公历日 * @param shiChen 时辰 * * @return String[4] 纪年,纪月,纪日,纪时 * **/ public static String[] getBaZi(int year, int month, int day, ShiChen shiChen){ String[] baZi = new String[4]; Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month - 1); calendar.set(Calendar.DAY_OF_MONTH, day); calendar.set(Calendar.HOUR_OF_DAY, 1); if (shiChen == ShiChen.晚子){// 子时需要往后推移一天 long time = calendar.getTimeInMillis() + 24*3600*1000; calendar.clear(); calendar.setTimeInMillis(time); year = calendar.get(Calendar.YEAR); month = calendar.get(Calendar.MONTH) + 1; day = calendar.get(Calendar.DAY_OF_MONTH); } int[] lunarDate = getLunarDateFromDate(calendar.getTime()); baZi[0] = getJiNian(lunarDate[0]); baZi[1] = getJiYue(lunarDate[0], Math.abs(lunarDate[1])); baZi[2] = getJiRi(year, month, day); baZi[3] = getJiShi(year, month, day, shiChen); return baZi; }
/** * 批八字 * @param lunarYear 农历年 * @param lunarMonth 农历月 * @param lunarDay 农历日 * @param shiChen 时辰 * * @return String[4] 纪年,纪月,纪日,纪时 * **/ public static String[] getBaZiByLunar(int lunarYear, int lunarMonth, int lunarDay, ShiChen shiChen){ String[] baZi = new String[4]; Date date = getDateFromLunarDate(lunarYear, lunarMonth, lunarDay); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH) + 1; int day = calendar.get(Calendar.DAY_OF_MONTH); if (shiChen == ShiChen.晚子){// 子时需要往后推移一天 long time = calendar.getTimeInMillis() + 24*3600*1000; calendar.clear(); calendar.setTimeInMillis(time); year = calendar.get(Calendar.YEAR); month = calendar.get(Calendar.MONTH) + 1; day = calendar.get(Calendar.DAY_OF_MONTH); } int[] lunarDate = getLunarDateFromDate(date); baZi[0] = getJiNian(lunarDate[0]); baZi[1] = getJiYue(lunarDate[0], Math.abs(lunarDate[1])); baZi[2] = getJiRi(year, month, day); baZi[3] = getJiShi(year, month, day, shiChen); return baZi; }
/** * 纪年 * * **/ public static String getJiNian(int lunarYear){ return getYearTianGan(lunarYear).getDesc() + getYearDiZhi(lunarYear); } /** * 获取纪月(纪月法) * @param lunarYear 农历年 * @param lunarMonth 农历月 * * **/ public static String getJiYue(int lunarYear,@IntRange(from = 1, to = 12) int lunarMonth){ TianGan tianGan = getYearTianGan(lunarYear); for (int i = 0; i< JI_YUE_TIAN_GAN.length; i++){ String jytg = JI_YUE_TIAN_GAN[i]; if (jytg.contains(tianGan.getDesc())){ return JI_YUE[i][lunarMonth-1]; } } return ""; } /** * 纪日 * * @param year 公历年 * @param month 公历月 * @param day 公历日 * * **/ public static String getJiRi(int year, int month, int day){ return getDayTianGan(year, month, day).getDesc() + getDayDiZhi(year, month, day).getDesc(); } /** * 纪时 * @param year 公历年 * @param month 公历月 * @param day 公历日 * @param shiChen 时辰 * **/ public static String getJiShi(int year, int month, int day, ShiChen shiChen){ TianGan tianGan = getDayTianGan(year, month, day); for (int i =0 ; i < JI_YUE_TIAN_GAN.length ; i++){ String jytg = JI_YUE_TIAN_GAN[i]; if (jytg.contains(tianGan.getDesc())){ if (shiChen == ShiChen.早子){ return "早" + JI_SHI[i][0]; }else if (shiChen == ShiChen.晚子){ return "晚" + JI_SHI[i][0]; } return JI_SHI[i][shiChen.getCode()]; } } return ""; }
/** * 获取年 天干 * @param lunarYear 农历年 * * **/ public static TianGan getYearTianGan(int lunarYear){ String temp = String.format("%s",(lunarYear - 3)); int tg = Integer.parseInt(temp.substring(temp.length()-1)); if (tg == 0)tg =10; return TianGan.getByCode(tg); } /** * 获取年 地支 * @param lunarYear 农历年 * * **/ public static DiZhi getYearDiZhi(int lunarYear){ int dz = (lunarYear -3)%12; if (dz == 0)dz = 12; return DiZhi.getByCode(dz); } /** * 获取 日天干 * @param year 公历年 * @param month 公历月 * @param day 公历日 * * **/ public static TianGan getDayTianGan(int year, int month, int day){ int shiJi = year/100 + (year%100 > 0 ? 1 : 0);//世纪 int yearYue = year%100; int tianGan = 4*(shiJi - 1) + (shiJi -1)/4 + 5* yearYue + yearYue/4 + (int)(3*(month + 1)/5f) + day - 3; return TianGan.getByCode(tianGan%10); } /** * 获取 日地支 * @param year 公历年 * @param month 公历月 * @param day 公历日 * * **/ public static DiZhi getDayDiZhi(int year, int month, int day){ int shiJi = year/100 + (year%100 > 0 ? 1 : 0);//世纪 int yearYue = year%100; int diZhi = 8*(shiJi - 1) + (shiJi -1)/4 + 5* yearYue + yearYue/4 + (int)(3*(month + 1)/5f) + day +7 + (month%2 == 0 ? 6 : 0); return DiZhi.getByCode(diZhi%12); }
农历转换公历,请参考: