java 阳历日期时间获取年月日时干支

您所在的位置:网站首页 如何推算农历日干支 java 阳历日期时间获取年月日时干支

java 阳历日期时间获取年月日时干支

2024-06-01 13:03| 来源: 网络整理| 查看: 265

某一天看日历的时候,突然注意到日历里的干支,了解了一下,感觉很有意思,想搜一下怎么用java实现,发现很多只有计算年干支,没有月日时,于是就写了个工具类,年月时参考了百度百科里的计算方式,日干支的计算公式是使用《高氏日柱公式》

日干支参考高氏日柱公式 年、月、时干支参考百度百科

 依赖hutool

cn.hutool hutool-all 5.5.1

 计算年月日时干支工具类

import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import java.util.*; /** * 获取阳历日期的年月日时干支 只支持1900-02-04至2050-01-22 (1900-02-04前按节气划分为1989年,2050-01-22之后为农历二〇五〇年,转阴历用的lunarInfo只到2049年) * 日干支参考: https://zhuanlan.zhihu.com/p/93508430 * 年、月、时干支参考百度百科: https://baike.baidu.com/item/%E5%A4%A9%E5%B9%B2%E5%9C%B0%E6%94%AF/278140?fromModule=lemma-qiyi_sense-lemma * * @author Administrator */ public class DateStemBranchUtils { protected static final String[] HEAVENLY_STEM = {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"}; protected static final String[] EARTHLY_BRANCHES = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; /** * 时辰数组 */ protected static final Integer[][] HOUR_ARRAY = {{23, 1}, {1, 3}, {3, 5}, {5, 7}, {7, 9}, {9, 11}, {11, 13}, {13, 15}, {15, 17}, {17, 19}, {19, 21}, {21, 23}}; /** * 按照年份计算世纪 * 此方法只应用于计算世纪常数,每个00年3月后记为新世纪 * * @param year * @return */ private static int centuryFromYear(int year, int month) { // 每个00年3月后记为新世纪 if (year % 100 == 0 && month < 3) { year = year / 100; } else { year = (year / 100) + 1; } return year; } /** * 计算世纪常数 * (ⅰ)每世纪的第一年是从“0”开始的,故整百整千的“世纪年”即为每世纪的第一年。例如:1900年为20世纪的第1年,其公元年份后两位为零,即s=0。 *

* (ⅱ)世纪常数x每世纪第一年3月1日的的日柱序列数减1。 * 例如:21世纪的世纪常数等于2000年3月1日的日柱(戊午)序列数减1,即x=55-1=54,同时也是-6(由于干支序列的60循环特点,而54-60=-6,在干支计算上54与-6是等价的)。 * * @param year * @return 世纪常数 */ private static int getCenturyConstant(int year, int month) { // 世纪数 区分16世纪前后 int x = 0; int n = centuryFromYear(year, month); if (n 16) { x = 44 * (n - 17) + (n - 17) / 4 - 3; } return x; } /** * 1582年10月15日—1599年14月29日”期间的日柱时,必须在算式最后再减去10 其他时间无需如此。 */ public static int containsSpecialDuration(int year, int month, int day) { int m = month < 3 ? (month + 12) : month; if (year > 1600 || year < 1582) { return 0; } if (year == 1582 && (m * 100 + day) < 1015) { return 0; } if (year == 1599 && (m * 100 + day) > 1429) { return 0; } return 10; } /** * 计算日干支数(干支表顺序) * * @param date * @return */ public static int getStemsBranch(Date date) { int monthNum = DateUtil.month(date) + 1; int yearNum = DateUtil.year(date); int mon = monthNum < 3 ? (monthNum + 12) : monthNum; String year = String.valueOf(yearNum); // s:公元年数后两位数, 取整数值,month < 3时,年份-1(当成前一年算) int s; if (monthNum < 3) { if (yearNum % 100 == 0) { s = 99; } else { s = Integer.parseInt(year.substring(2)) - 1; } } else { s = Integer.parseInt(year.substring(2)); } int sd4 = s / 4; // u:s除以4的余数 int u = s % 4; int cal = (3 * mon - 7) / 5; // m:月数 int m = (int) (30 * ((Math.pow(-1, mon) + 1) / 2) + cal); // d:日期数 int d = DateUtil.dayOfMonth(date); // x:世纪常数 int x = getCenturyConstant(yearNum, monthNum) % 60; // 在计算“1582年10月15日—1599年14月29日”期间的日柱时,必须在算式最后再减去10 int specialDuration = containsSpecialDuration(yearNum, monthNum, d); // r 日柱的母数,r 除以60的余数即是日柱的干支序列数 公式:r=s/4×6+5(s/4×3+u)+m+d+x int r = (sd4 * 6) + (5 * (sd4 * 3 + u)) + m + d + x - specialDuration; int res = r % 60; return res == 0 ? 60 : res; } /** * 计算年干支(公元后) * 干:甲=4…… 支:子=4…… * * @param year 阴历年份 * @return 年干支 */ public static String calYearStemBranch(int year) { String strYear = String.valueOf(year); int lastDigitOfYear = Integer.parseInt(strYear.substring(strYear.length() - 1)); // 按照天干下标从0开始,年份最后一位(= 23; int stemIndex = nextDay ? zeroStemIndex + branchIndex + 2 : zeroStemIndex + branchIndex; // 时干下标 stemIndex = stemIndex > 9 ? stemIndex - 10 : stemIndex; return HEAVENLY_STEM[stemIndex] + EARTHLY_BRANCHES[branchIndex] + "时"; } /** * 阳历日期计算 年月日时干支 * 年用阴历年份算,正月初一为一年开始 * 月用节气划分的月算,立春为一年开始 * 日用阳历算 * * @param dateTime yyyy-MM-dd HH:mm:ss * @return 阴历日期 + 年干支 + 生肖 + 月日时干支 */ public static String calStemBranch(String dateTime) { DateTime parse = DateUtil.parse(dateTime, DatePattern.NORM_DATETIME_PATTERN); String date = DateUtil.format(parse, DatePattern.NORM_DATE_PATTERN); // 获取阴历日期(yyyy-MM-dd) 阴历会有二月三十,获取不能转阳历格式,用split代替 String lunarCalendar = LunarCalendarFestivalUtils.toLunarCalendar(date); // 阴历日期(一九九六年 五月三十) String calendar = LunarCalendarFestivalUtils.getLunarCalendar(date); // 阴历年份 int year = Integer.parseInt(lunarCalendar.split("-")[0]); // 年干支 String yearStemBranch = calYearStemBranch(year); // 计算干支纪月的年、月按照节气算,立春开始算正月,两个节气一个月 int lunarTermYear = LunarCalendarFestivalUtils.getLunarTermYear(date); int lunarTermMonth = LunarCalendarFestivalUtils.getLunarTermMonth(date); // 月干支 String monthStemBranch = calMonthStemBranch(lunarTermYear, lunarTermMonth); // 日干支 String dayStemBranch = calDayStemBranch(date); // 获取日干下标 int dayStem = LunarCalendarFestivalUtils.printArray(HEAVENLY_STEM, dayStemBranch.substring(0, 1)); // 计算时干支 String hourStemBranch = calHourStemBranch(DateUtil.hour(parse, true), dayStem); return calendar + " " + yearStemBranch + monthStemBranch + dayStemBranch + " " + hourStemBranch; } public static void main(String[] args) { String stemBranch = calStemBranch("2050-01-22 00:00:00"); System.out.println(stemBranch); } }

 阳历转阴历工具类

import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; /** * 获取输入公历日期的生肖、天干地支、农历年、农历月、农历日、公历节日、农历节日、24节气等数据 * DATE 2020.08.13 * 转自 https://zhuanlan.zhihu.com/p/293819435 * 阴历96年修正参考 https://blog.csdn.net/shuaiziyihao/article/details/46841843 */ public class LunarCalendarFestivalUtils { //生肖年 private String animal; //干支年 private String ganZhiYear; //阴历年 private String lunarYear; private int lunarYearNum; //阴历月 private String lunarMonth; private int lunarMonthNum; //阴历日 private String lunarDay; private int lunarDayNum; //阳历节日 private String solarFestival; //阴历节日 private String lunarFestival; //节气 private String lunarTerm; /** * 获取查询日期的年份生肖 * * @return */ public String getAnimal() { return animal; } /** * 获取查询日期年份的天干地支 * * @return */ public String getGanZhiYear() { return ganZhiYear; } /** * 获取查询日期的农历年份 * * @return */ public String getLunarYear() { return lunarYear; } /** * 获取查询日期的农历月份 * * @return */ public String getLunarMonth() { return lunarMonth; } /** * 获取查询日期的农历日 * * @return */ public String getLunarDay() { return lunarDay; } /** * 获取查询日期的公历节日(不是节日返回空) * * @return */ public String getSolarFestival() { return solarFestival; } /** * 获取查询日期的农历节日(不是节日返回空) * * @return */ public String getLunarFestival() { return lunarFestival; } /** * 获取查询日期的节气数据(不是节气返回空) * * @return */ public String getLunarTerm() { return lunarTerm; } public int getLunarYearNum() { return lunarYearNum; } public int getLunarMonthNum() { return lunarMonthNum; } public int getLunarDayNum() { return lunarDayNum; } // 修正1996 0x055c0 -> 0x059c0 final static long[] lunarInfo = new long[]{ 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x059c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 }; //阳历天数 final static int[] solarMonths = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //生肖 final static String[] animals = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"}; //天干 final static String[] tGan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"}; //地支 final static String[] dZhi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; //二十四节气 final static String[] solarTerms = new String[]{"小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"}; // 划分月份的十二个节气 static final String[] terms = new String[]{"立春", "惊蛰", "清明", "立夏", "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪", "小寒"}; //二十四节气日期偏移度 private static final double D = 0.2422; //特殊年份节气日期偏移 private final static Map INCREASE_OFFSETMAP = new HashMap();//+1偏移 private final static Map DECREASE_OFFSETMAP = new HashMap();//-1偏移 static { INCREASE_OFFSETMAP.put(0, new Integer[]{1982});//小寒 DECREASE_OFFSETMAP.put(0, new Integer[]{2019});//小寒 INCREASE_OFFSETMAP.put(1, new Integer[]{2082});//大寒 DECREASE_OFFSETMAP.put(3, new Integer[]{2026});//雨水 INCREASE_OFFSETMAP.put(5, new Integer[]{2084});//春分 INCREASE_OFFSETMAP.put(9, new Integer[]{2008});//小满 INCREASE_OFFSETMAP.put(10, new Integer[]{1902});//芒种 INCREASE_OFFSETMAP.put(11, new Integer[]{1928});//夏至 INCREASE_OFFSETMAP.put(12, new Integer[]{1925, 2016});//小暑 INCREASE_OFFSETMAP.put(13, new Integer[]{1922});//大暑 INCREASE_OFFSETMAP.put(14, new Integer[]{2002});//立秋 INCREASE_OFFSETMAP.put(16, new Integer[]{1927});//白露 INCREASE_OFFSETMAP.put(17, new Integer[]{1942});//秋分 INCREASE_OFFSETMAP.put(19, new Integer[]{2089});//霜降 INCREASE_OFFSETMAP.put(20, new Integer[]{2089});//立冬 INCREASE_OFFSETMAP.put(21, new Integer[]{1978});//小雪 INCREASE_OFFSETMAP.put(22, new Integer[]{1954});//大雪 DECREASE_OFFSETMAP.put(23, new Integer[]{1918, 2021});//冬至 } //定义一个二维数组,第一维数组存储的是20世纪的节气C值,第二维数组存储的是21世纪的节气C值,0到23个,依次代表立春、雨水...大寒节气的C值 private static final double[][] CENTURY_ARRAY = { {6.11, 20.84, 4.6295, 19.4599, 6.3826, 21.4155, 5.59, 20.888, 6.318, 21.86, 6.5, 22.2, 7.928, 23.65, 8.35, 23.95, 8.44, 23.822, 9.098, 24.218, 8.218, 23.08, 7.9, 22.6}, {5.4055, 20.12, 3.87, 18.73, 5.63, 20.646, 4.81, 20.1, 5.52, 21.04, 5.678, 21.37, 7.108, 22.83, 7.5, 23.13, 7.646, 23.042, 8.318, 23.438, 7.438, 22.36, 7.18, 21.94} }; //农历月份 final static String lunarNumber[] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"}; //农历年 final static String[] lunarYears = new String[]{"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"}; final static String[] chineseTen = new String[]{"初", "十", "廿", "三"}; //农历节日 final static String[] lunarHoliday = new String[]{"0101 春节", "0115 元宵节", "0202 龙头节", "0505 端午节", "0707 七夕节", "0715 中元节", "0815 中秋节", "0909 重阳节", "1001 寒衣节", "1015 下元节", "1208 腊八节", "1223 小年"}; //公立节日 final static String[] solarHoliday = new String[]{"0101 元旦", "0214 情人节", "0308 妇女节", "0312 植树节", "0315 消费者权益日", "0401 愚人节", "0422 地球日", "0423 读书日", "0501 劳动节", "0504 青年节", "0512 护士节", "0518 博物馆日", "0519 旅游日", "0601 儿童节", "0701 建党节", "0801 建军节", "0910 教师节", "1001 国庆节", "1024 联合国日", "1204 宪法日", "1224 平安夜", "1225 圣诞节"}; //格式化日期 static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA); static SimpleDateFormat solarDateFormat = new SimpleDateFormat("yyyy-MM-dd"); /** * 返回农历y年的总天数 * * @param y * @return */ private int lunarYearDays(int y) { int i, sum = 348; for (i = 0x8000; i > 0x8; i >>= 1) { sum += ((lunarInfo[y - 1900] & i) != 0 ? 1 : 0); } return (sum + leapDays(y)); } /** * 返回农历y年闰月的天数 */ private int leapDays(int y) { if (leapMonth(y) != 0) { return ((lunarInfo[y - 1900] & 0x10000) != 0 ? 30 : 29); } else { return 0; } } /** * 判断y年的农历中那个月是闰月,不是闰月返回0 * * @param y * @return */ private int leapMonth(int y) { return (int) (lunarInfo[y - 1900] & 0xf); } /** * 返回农历y年m月的总天数 * * @param y * @param m * @return */ private int monthDays(int y, int m) { return ((lunarInfo[y - 1900] & (0x10000 >> m)) != 0 ? 30 : 29); } /** * 获取阴历年 * * @param year * @return */ private String getLunarYearString(String year) { int y1 = Integer.parseInt(year.charAt(0) + ""); int y2 = Integer.parseInt(year.charAt(1) + ""); int y3 = Integer.parseInt(year.charAt(2) + ""); int y4 = Integer.parseInt(year.charAt(3) + ""); return lunarYears[y1] + lunarYears[y2] + lunarYears[y3] + lunarYears[y4]; } /** * 获取阴历日 */ private String getLunarDayString(int day) { int n = day % 10 == 0 ? 9 : day % 10 - 1; if (day > 30) { return ""; } if (day == 10) { return "初十"; } else { return chineseTen[day / 10] + lunarNumber[n]; } } /** * 特例,特殊的年分的节气偏移量,由于公式并不完善,所以算出的个别节气的第几天数并不准确,在此返回其偏移量 * * @param year 年份 * @param n 节气编号 * @return 返回其偏移量 */ private static int specialYearOffset(int year, int n) { int offset = 0; offset += getOffset(DECREASE_OFFSETMAP, year, n, -1); offset += getOffset(INCREASE_OFFSETMAP, year, n, 1); return offset; } /** * 节气偏移量计算 * * @param map * @param year * @param n * @param offset * @return */ private static int getOffset(Map map, int year, int n, int offset) { int off = 0; Integer[] years = map.get(n); if (null != years) { for (int i : years) { if (i == year) { off = offset; break; } } } return off; } /** * 获取某年的第n个节气为几日(从0小寒起算) * * @param year * @param n * @return */ private static int sTerm(int year, int n) { double centuryValue = 0;//节气的世纪值,每个节气的每个世纪值都不同 int centuryIndex = -1; if (year >= 1900 && year = 2001 && year 0; iYear++) { daysOfYear = lunarYearDays(iYear); offset -= daysOfYear; } if (offset < 0) { offset += daysOfYear; iYear--; } this.lunarYear = getLunarYearString(iYear + ""); this.lunarYearNum = iYear; int leapMonth = leapMonth(iYear); // 闰哪个月,1-12 boolean leap = false; // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天 int iMonth, daysOfMonth = 0; for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) { // 闰月 if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) { --iMonth; leap = true; daysOfMonth = leapDays(iYear); } else { daysOfMonth = monthDays(iYear, iMonth); } offset -= daysOfMonth; // 解除闰月 if (leap && iMonth == (leapMonth + 1)) { leap = false; } } // offset为0时,并且刚才计算的月份是闰月,要校正 if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) { if (leap) { leap = false; } else { leap = true; --iMonth; } } // offset小于0时,也要校正 if (offset < 0) { offset += daysOfMonth; --iMonth; } // 设置对应的阴历月份 this.lunarMonth = lunarNumber[iMonth - 1]; this.lunarMonthNum = iMonth; if ("一".equals(this.lunarMonth)) { this.lunarMonth = "正"; } if ("十二".equals(this.lunarMonth)) { this.lunarMonth = "腊"; } if (leap) { this.lunarMonth = "闰" + this.lunarMonth; } //设置阴历日 int iDay = offset + 1; this.lunarDay = getLunarDayString(iDay); this.lunarDayNum = iDay; //设置节气 int month = Integer.parseInt(splitDate[1]); int day = Integer.parseInt(splitDate[2]); if (day == sTerm(year, (month - 1) * 2)) { this.lunarTerm = solarTerms[(month - 1) * 2]; } else if (day == sTerm(year, (month - 1) * 2 + 1)) { this.lunarTerm = solarTerms[(month - 1) * 2 + 1]; } else { this.lunarTerm = ""; } //设置阴历节日 String lunarFestival = ""; for (int i = 0; i < lunarHoliday.length; i++) { //阴历闰月节日 if (leap) { break; } // 返回农历节假日名称 String ld = lunarHoliday[i].split(" ")[0]; // 节假日的日期 String ldv = lunarHoliday[i].split(" ")[1]; // 节假日的名称 String lmonth_v = iMonth + ""; String lday_v = iDay + ""; String lmd = ""; if (iMonth < 10) { lmonth_v = "0" + iMonth; } if (iDay < 10) { lday_v = "0" + iDay; } lmd = lmonth_v + lday_v; if ("12".equals(lmonth_v)) { // 除夕夜需要特殊处理 if ((daysOfMonth == 29 && iDay == 29) || (daysOfMonth == 30 && iDay == 30)) { lunarFestival = "除夕"; break; } } if (ld.trim().equals(lmd.trim())) { lunarFestival = ldv; break; } } if ("清明".equals(this.lunarTerm)) { lunarFestival = "清明节"; } this.lunarFestival = lunarFestival; } // ==============================以下方法为在原有基础下追加================================= /** * 阳历日期转阴历 * * @param date 阳历 yyyy-MM-dd * @return 阴历 yyyy-MM-dd */ public static String toLunarCalendar(String date) { LunarCalendarFestivalUtils festival = new LunarCalendarFestivalUtils(); festival.initLunarCalendarInfo(date); return festival.getLunarYearNum() + "-" + String.format("%02d", festival.getLunarMonthNum()) + "-" + String.format("%02d", festival.getLunarDayNum()); } /** * 获取阴历日期 * @param date 阳历日期 * @return 阴历大写日期 */ public static String getLunarCalendar(String date) { LunarCalendarFestivalUtils festival = new LunarCalendarFestivalUtils(); festival.initLunarCalendarInfo(date); return festival.getLunarYear() + "年 " + festival.getLunarMonth() + "月" + festival.getLunarDay(); } /** * 遍历数组 获取元素在数组的下标 * @param array 数组 * @param value 元素 * @return 下标 */ public static int printArray(String[] array, String value) { for (int i = 0; i < array.length; i++) { if (Objects.equals(array[i], value)) { return i; } } return -1;//当if条件不成立时,默认返回一个负数值-1 } /** * 获取某年的第n个节气为几日(从0小寒起算) * * @param year 年 * @param month 月 * @param n 节气顺序 从0小寒起算 * @return 阳历日期 */ private static String getLunarTermDay(int year, int month, int n) { int day = sTerm(year, n); // 拼成节气的阳历日期 return year + "-" + String.format("%02d", month) + "-" + String.format("%02d", day); } /** * 按节气划分月份 * @param date 阳历日期 * @return 干支纪月的月份 (节气划分的月份) */ public static int getLunarTermMonth(String date) { // 获取以节气划分的年份 int year = getLunarTermYear(date); // 从2月开始获取本年每月第一个节气、下一年的1月第一个节气,还有下一年的立春日期 String[] solarTermDates = new String[13]; for (int i = 0; i < terms.length; i++) { String solarTermDate; // 小寒 当年的1月是上一年的小寒,本年的小寒在下一年1月 if (i == terms.length - 1) { solarTermDate = getLunarTermDay(year + 1, 1, printArray(solarTerms, terms[i])); } else { // 节气的日期(阳历) 立春-大雪 solarTermDate = getLunarTermDay(year, i + 2, printArray(solarTerms, terms[i])); } // 节气日期 solarTermDates[i] = solarTermDate; } // 获取下一年的立春日期 solarTermDates[12] = getLunarTermDay(year + 1, 2, printArray(solarTerms, terms[0])); // 按节气划分月份 String[][] dateScope = new String[12][2]; for (int i = 0; i < dateScope.length; i++) { dateScope[i][0] = solarTermDates[i]; dateScope[i][1] = solarTermDates[i + 1]; } // dateScope 下标+1就是干支纪月的月份 for (int i = 0; i < dateScope.length; i++) { // if 日期在某两个节气区间 if (DateUtil.isIn(DateUtil.parse(date, DatePattern.NORM_DATE_PATTERN), DateUtil.parse(dateScope[i][0], DatePattern.NORM_DATE_PATTERN), DateUtil.offsetDay(DateUtil.parse(dateScope[i][1], DatePattern.NORM_DATE_PATTERN), -1)) ) { return i + 1; } } return 0; } /** * 按节气划分年份 * @param date 阳历日期 * @return 干支纪月的年份 立春前算前一年 */ public static int getLunarTermYear(String date) { String[] splitDate = date.split("-"); int year = Integer.parseInt(splitDate[0]); // 获取当年立春,确定日期在立春前后,立春前需要按照上一年算, 当前日期 < 立春时,年份-1 String currSpringDate = getLunarTermDay(year, 2, printArray(solarTerms, terms[0])); if (DateUtil.compare(DateUtil.parse(date, DatePattern.NORM_DATE_PATTERN), DateUtil.parse(currSpringDate, DatePattern.NORM_DATE_PATTERN)) < 0) { year = year - 1; } return year; } }

 结果示例:

一九九六年 六月初一 丙子鼠年乙未月甲寅日 甲子时



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3