Browse Source

!169 干支纪年转换拓展

Merge pull request !169 from dcbai/v5-dev
Looly 5 years ago
parent
commit
be6d287b6b

+ 247 - 29
hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java

@@ -4,9 +4,12 @@ import cn.hutool.core.convert.NumberChineseFormatter;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.Date;
 import java.util.List;
 import java.util.List;
 
 
+import static cn.hutool.core.util.NumberUtil.parseInt;
+
 
 
 /**
 /**
  * 农历日期工具,最大支持到2055年
  * 农历日期工具,最大支持到2055年
@@ -15,52 +18,128 @@ import java.util.List;
  * @since 5.1.1
  * @since 5.1.1
  */
  */
 public class ChineseDate {
 public class ChineseDate {
-
 //	private static final Date baseDate = DateUtil.parseDate("1900-01-31");
 //	private static final Date baseDate = DateUtil.parseDate("1900-01-31");
 	/**
 	/**
 	 * 1900-01-31
 	 * 1900-01-31
 	 */
 	 */
 	private static final long baseDate = -2206425943000L;
 	private static final long baseDate = -2206425943000L;
-
 	//农历年
 	//农历年
 	private final int year;
 	private final int year;
 	//农历月
 	//农历月
 	private final int month;
 	private final int month;
 	//农历日
 	//农历日
 	private final int day;
 	private final int day;
+	//公历年
+	private final int gyear;
+	//公历月
+	private final int gmonth;
+	//公里日
+	private final int gday;
 	//是否闰年
 	//是否闰年
 	private boolean leap;
 	private boolean leap;
 	private final String[] chineseNumber = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
 	private final String[] chineseNumber = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
 	private final String[] chineseNumberName = {"正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊"};
 	private final String[] chineseNumberName = {"正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊"};
 	/**
 	/**
 	 * 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js
 	 * 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js
-	 *农历表示:
+	 * 农历表示:
 	 * 1.  表示当年有无闰年,有的话,为闰月的月份,没有的话,为0。
 	 * 1.  表示当年有无闰年,有的话,为闰月的月份,没有的话,为0。
 	 * 2-4.为除了闰月外的正常月份是大月还是小月,1为30天,0为29天。
 	 * 2-4.为除了闰月外的正常月份是大月还是小月,1为30天,0为29天。
 	 * 5.  表示闰月是大月还是小月,仅当存在闰月的情况下有意义。
 	 * 5.  表示闰月是大月还是小月,仅当存在闰月的情况下有意义。
 	 */
 	 */
 	private final long[] lunarInfo = new long[]{
 	private final long[] lunarInfo = new long[]{
-			0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909
-			0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919
-			0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929
-			0x06566,0x0d4a0,0x0ea50,0x16a95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939
-			0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949
-			0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959
-			0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969
-			0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979
-			0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989
-			0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x05ac0,0x0ab60,0x096d5,0x092e0,//1990-1999
-			0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009
-			0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019
-			0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029
-			0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039
-			0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049
-			0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059
-			0x092e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069
-			0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079
-			0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089
-			0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099
+			0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,//1900-1909
+			0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,//1910-1919
+			0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,//1920-1929
+			0x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,//1930-1939
+			0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,//1940-1949
+			0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0,//1950-1959
+			0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,//1960-1969
+			0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6,//1970-1979
+			0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,//1980-1989
+			0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0,//1990-1999
+			0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,//2000-2009
+			0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,//2010-2019
+			0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,//2020-2029
+			0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,//2030-2039
+			0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0,//2040-2049
+			0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0,//2050-2059
+			0x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4,//2060-2069
+			0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0,//2070-2079
+			0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160,//2080-2089
+			0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252,//2090-2099
 	};
 	};
+	/**
+	 * 1900-2100各年的24节气日期速查表
+	 * 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js
+	 */
+	private final String[] sTermInfo = new String[]{
+			"9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e", "97bcf97c3598082c95f8c965cc920f",
+			"97bd0b06bdb0722c965ce1cfcc920f", "b027097bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+			"97bcf97c359801ec95f8c965cc920f", "97bd0b06bdb0722c965ce1cfcc920f", "b027097bd097c36b0b6fc9274c91aa",
+			"97b6b97bd19801ec9210c965cc920e", "97bcf97c359801ec95f8c965cc920f", "97bd0b06bdb0722c965ce1cfcc920f",
+			"b027097bd097c36b0b6fc9274c91aa", "9778397bd19801ec9210c965cc920e", "97b6b97bd19801ec95f8c965cc920f",
+			"97bd09801d98082c95f8e1cfcc920f", "97bd097bd097c36b0b6fc9210c8dc2", "9778397bd197c36c9210c9274c91aa",
+			"97b6b97bd19801ec95f8c965cc920e", "97bd09801d98082c95f8e1cfcc920f", "97bd097bd097c36b0b6fc9210c8dc2",
+			"9778397bd097c36c9210c9274c91aa", "97b6b97bd19801ec95f8c965cc920e", "97bcf97c3598082c95f8e1cfcc920f",
+			"97bd097bd097c36b0b6fc9210c8dc2", "9778397bd097c36c9210c9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+			"97bcf97c3598082c95f8c965cc920f", "97bd097bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+			"97b6b97bd19801ec9210c965cc920e", "97bcf97c3598082c95f8c965cc920f", "97bd097bd097c35b0b6fc920fb0722",
+			"9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e", "97bcf97c359801ec95f8c965cc920f",
+			"97bd097bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+			"97bcf97c359801ec95f8c965cc920f", "97bd097bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+			"97b6b97bd19801ec9210c965cc920e", "97bcf97c359801ec95f8c965cc920f", "97bd097bd07f595b0b6fc920fb0722",
+			"9778397bd097c36b0b6fc9210c8dc2", "9778397bd19801ec9210c9274c920e", "97b6b97bd19801ec95f8c965cc920f",
+			"97bd07f5307f595b0b0bc920fb0722", "7f0e397bd097c36b0b6fc9210c8dc2", "9778397bd097c36c9210c9274c920e",
+			"97b6b97bd19801ec95f8c965cc920f", "97bd07f5307f595b0b0bc920fb0722", "7f0e397bd097c36b0b6fc9210c8dc2",
+			"9778397bd097c36c9210c9274c91aa", "97b6b97bd19801ec9210c965cc920e", "97bd07f1487f595b0b0bc920fb0722",
+			"7f0e397bd097c36b0b6fc9210c8dc2", "9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+			"97bcf7f1487f595b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+			"97b6b97bd19801ec9210c965cc920e", "97bcf7f1487f595b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722",
+			"9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e", "97bcf7f1487f531b0b0bb0b6fb0722",
+			"7f0e397bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+			"97bcf7f1487f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+			"97b6b97bd19801ec9210c9274c920e", "97bcf7f0e47f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722",
+			"9778397bd097c36b0b6fc9210c91aa", "97b6b97bd197c36c9210c9274c920e", "97bcf7f0e47f531b0b0bb0b6fb0722",
+			"7f0e397bd07f595b0b0bc920fb0722", "9778397bd097c36b0b6fc9210c8dc2", "9778397bd097c36c9210c9274c920e",
+			"97b6b7f0e47f531b0723b0b6fb0722", "7f0e37f5307f595b0b0bc920fb0722", "7f0e397bd097c36b0b6fc9210c8dc2",
+			"9778397bd097c36b0b70c9274c91aa", "97b6b7f0e47f531b0723b0b6fb0721", "7f0e37f1487f595b0b0bb0b6fb0722",
+			"7f0e397bd097c35b0b6fc9210c8dc2", "9778397bd097c36b0b6fc9274c91aa", "97b6b7f0e47f531b0723b0b6fb0721",
+			"7f0e27f1487f595b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+			"97b6b7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722",
+			"9778397bd097c36b0b6fc9274c91aa", "97b6b7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722",
+			"7f0e397bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa", "97b6b7f0e47f531b0723b0b6fb0721",
+			"7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+			"97b6b7f0e47f531b0723b0787b0721", "7f0e27f0e47f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722",
+			"9778397bd097c36b0b6fc9210c91aa", "97b6b7f0e47f149b0723b0787b0721", "7f0e27f0e47f531b0723b0b6fb0722",
+			"7f0e397bd07f595b0b0bc920fb0722", "9778397bd097c36b0b6fc9210c8dc2", "977837f0e37f149b0723b0787b0721",
+			"7f07e7f0e47f531b0723b0b6fb0722", "7f0e37f5307f595b0b0bc920fb0722", "7f0e397bd097c35b0b6fc9210c8dc2",
+			"977837f0e37f14998082b0787b0721", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e37f1487f595b0b0bb0b6fb0722",
+			"7f0e397bd097c35b0b6fc9210c8dc2", "977837f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721",
+			"7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722", "977837f0e37f14998082b0787b06bd",
+			"7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722",
+			"977837f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722",
+			"7f0e397bd07f595b0b0bc920fb0722", "977837f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721",
+			"7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722", "977837f0e37f14998082b0787b06bd",
+			"7f07e7f0e47f149b0723b0787b0721", "7f0e27f0e47f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722",
+			"977837f0e37f14998082b0723b06bd", "7f07e7f0e37f149b0723b0787b0721", "7f0e27f0e47f531b0723b0b6fb0722",
+			"7f0e397bd07f595b0b0bc920fb0722", "977837f0e37f14898082b0723b02d5", "7ec967f0e37f14998082b0787b0721",
+			"7f07e7f0e47f531b0723b0b6fb0722", "7f0e37f1487f595b0b0bb0b6fb0722", "7f0e37f0e37f14898082b0723b02d5",
+			"7ec967f0e37f14998082b0787b0721", "7f07e7f0e47f531b0723b0b6fb0722", "7f0e37f1487f531b0b0bb0b6fb0722",
+			"7f0e37f0e37f14898082b0723b02d5", "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721",
+			"7f0e37f1487f531b0b0bb0b6fb0722", "7f0e37f0e37f14898082b072297c35", "7ec967f0e37f14998082b0787b06bd",
+			"7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e37f0e37f14898082b072297c35",
+			"7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722",
+			"7f0e37f0e366aa89801eb072297c35", "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f149b0723b0787b0721",
+			"7f0e27f1487f531b0b0bb0b6fb0722", "7f0e37f0e366aa89801eb072297c35", "7ec967f0e37f14998082b0723b06bd",
+			"7f07e7f0e47f149b0723b0787b0721", "7f0e27f0e47f531b0723b0b6fb0722", "7f0e37f0e366aa89801eb072297c35",
+			"7ec967f0e37f14998082b0723b06bd", "7f07e7f0e37f14998083b0787b0721", "7f0e27f0e47f531b0723b0b6fb0722",
+			"7f0e37f0e366aa89801eb072297c35", "7ec967f0e37f14898082b0723b02d5", "7f07e7f0e37f14998082b0787b0721",
+			"7f07e7f0e47f531b0723b0b6fb0722", "7f0e36665b66aa89801e9808297c35", "665f67f0e37f14898082b0723b02d5",
+			"7ec967f0e37f14998082b0787b0721", "7f07e7f0e47f531b0723b0b6fb0722", "7f0e36665b66a449801e9808297c35",
+			"665f67f0e37f14898082b0723b02d5", "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721",
+			"7f0e36665b66a449801e9808297c35", "665f67f0e37f14898082b072297c35", "7ec967f0e37f14998082b0787b06bd",
+			"7f07e7f0e47f531b0723b0b6fb0721", "7f0e26665b66a449801e9808297c35", "665f67f0e37f1489801eb072297c35",
+			"7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722"};
 
 
 	//农历节日  *表示放假日
 	//农历节日  *表示放假日
 	private final String[] lFtv = new String[]{
 	private final String[] lFtv = new String[]{
@@ -70,7 +149,8 @@ public class ChineseDate {
 			"0408 佛诞节 ", "0505 端午节", "0606 天贶节 姑姑节", "0624 彝族火把节",
 			"0408 佛诞节 ", "0505 端午节", "0606 天贶节 姑姑节", "0624 彝族火把节",
 			"0707 七夕情人节", "0714 鬼节(南方)", "0715 盂兰节", "0730 地藏节",
 			"0707 七夕情人节", "0714 鬼节(南方)", "0715 盂兰节", "0730 地藏节",
 			"0815 中秋节", "0909 重阳节", "1001 祭祖节", "1117 阿弥陀佛圣诞",
 			"0815 中秋节", "0909 重阳节", "1001 祭祖节", "1117 阿弥陀佛圣诞",
-			"1208 腊八节 释迦如来成道日", "1223 过小年", "1229 腊月二十九", "1230 除夕"};
+			"1208 腊八节 释迦如来成道日", "1223 过小年", "1229 腊月二十九", "1230 除夕"
+	};
 
 
 	/**
 	/**
 	 * 构造方法传入日期
 	 * 构造方法传入日期
@@ -80,7 +160,6 @@ public class ChineseDate {
 	public ChineseDate(Date date) {
 	public ChineseDate(Date date) {
 		// 求出和1900年1月31日相差的天数
 		// 求出和1900年1月31日相差的天数
 		int offset = (int) ((date.getTime() - baseDate) / DateUnit.DAY.getMillis());
 		int offset = (int) ((date.getTime() - baseDate) / DateUnit.DAY.getMillis());
-
 		// 计算农历年份
 		// 计算农历年份
 		// 用offset减去每农历年的天数,计算当天是农历第几天,offset是当年的第几天
 		// 用offset减去每农历年的天数,计算当天是农历第几天,offset是当年的第几天
 		int daysOfYear;
 		int daysOfYear;
@@ -93,6 +172,9 @@ public class ChineseDate {
 			}
 			}
 			offset -= daysOfYear;
 			offset -= daysOfYear;
 		}
 		}
+		Calendar instance = Calendar.getInstance();
+		instance.setTime(date);
+		gyear = instance.get(Calendar.YEAR);
 		year = iYear;
 		year = iYear;
 
 
 		// 计算农历月份
 		// 计算农历月份
@@ -112,7 +194,7 @@ public class ChineseDate {
 
 
 			offset -= daysOfMonth;
 			offset -= daysOfMonth;
 			// 解除闰月
 			// 解除闰月
-			if (leap && iMonth == (leapMonth + 1)){
+			if (leap && iMonth == (leapMonth + 1)) {
 				leap = false;
 				leap = false;
 			}
 			}
 		}
 		}
@@ -126,14 +208,16 @@ public class ChineseDate {
 				--iMonth;
 				--iMonth;
 			}
 			}
 		}
 		}
-
 		// offset小于0时,也要校正
 		// offset小于0时,也要校正
 		if (offset < 0) {
 		if (offset < 0) {
 			offset += daysOfMonth;
 			offset += daysOfMonth;
 			--iMonth;
 			--iMonth;
 		}
 		}
+
 		month = iMonth;
 		month = iMonth;
+		gmonth = instance.get(Calendar.MARCH) + 1;
 		day = offset + 1;
 		day = offset + 1;
+		gday = instance.get(Calendar.DATE);
 	}
 	}
 
 
 	/**
 	/**
@@ -149,6 +233,24 @@ public class ChineseDate {
 		this.month = chineseMonth;
 		this.month = chineseMonth;
 		this.year = chineseYear;
 		this.year = chineseYear;
 		this.leap = DateUtil.isLeapYear(chineseYear);
 		this.leap = DateUtil.isLeapYear(chineseYear);
+		//先判断传入的月份是不是闰月
+		int leapMonth = this.leapMonth(chineseYear);
+		Integer[] integers = lunar2solar(chineseYear, chineseMonth, chineseDay, chineseMonth == leapMonth);
+		if (integers != null) {
+			//初始化公历年
+			this.gday = integers[2];
+			//初始化公历月
+			this.gmonth = integers[1];
+			//初始化公历日
+			this.gyear = integers[0];
+		} else {
+			//初始化公历年
+			this.gday = -1;
+			//初始化公历月
+			this.gmonth = -1;
+			//初始化公历日
+			this.gyear = -1;
+		}
 	}
 	}
 
 
 	/**
 	/**
@@ -170,6 +272,7 @@ public class ChineseDate {
 		return this.month;
 		return this.month;
 	}
 	}
 
 
+
 	/**
 	/**
 	 * 获得农历月份(中文,例如二月,十二月,或者润一月)
 	 * 获得农历月份(中文,例如二月,十二月,或者润一月)
 	 *
 	 *
@@ -270,6 +373,17 @@ public class ChineseDate {
 	}
 	}
 
 
 	/**
 	/**
+	 * 干支纪年信息
+	 *
+	 * @return 获得天干地支的年月日信息
+	 */
+	public String getCyclicalYMD() {
+		if (gyear >= 1900 && gmonth > 0 && gday > 0)
+			return (cyclicalm(gyear, gmonth, gday));
+		return "";
+	}
+
+	/**
 	 * 转换为标准的日期格式来表示农历日期,例如2020-01-13
 	 * 转换为标准的日期格式来表示农历日期,例如2020-01-13
 	 *
 	 *
 	 * @return 标准的日期格式
 	 * @return 标准的日期格式
@@ -296,6 +410,58 @@ public class ChineseDate {
 	}
 	}
 
 
 	/**
 	/**
+	 * 这里同步处理年月日的天干地支信息
+	 *
+	 * @param Y
+	 * @param M
+	 * @param D
+	 * @return
+	 */
+	private String cyclicalm(int Y, int M, int D) {
+		String gzyear = cyclicalm(year - 1900 + 36);
+		//天干地支处理
+		//返回当月「节」为几日开始
+		int firstNode = this.getTerm(Y, (M * 2 - 1));
+		// 依据12节气修正干支月
+		String gzM = this.cyclicalm((Y - 1900) * 12 + M + 11);
+		if (D >= firstNode) {
+			gzM = this.cyclicalm((Y - 1900) * 12 + M + 12);
+		}
+		int dayCyclical = (int) ((DateUtil.parseDate(Y + "-" + M + "-" + "1").getTime() - baseDate + 2592000000L) / DateUnit.DAY.getMillis()) + 10;
+		String gzD = this.cyclicalm(dayCyclical + D - 1);
+		return gzyear + "年" + gzM + "月" + gzD + "日";
+	}
+
+	/**
+	 * 根据节气修正干支月
+	 *
+	 * @param y
+	 * @param n
+	 * @return
+	 */
+	private int getTerm(int y, int n) {
+		if (y < 1900 || y > 2100) {
+			return -1;
+		}
+		if (n < 1 || n > 24) {
+			return -1;
+		}
+		String _table = this.sTermInfo[y - 1900];
+		Integer[] _info = new Integer[6];
+		for (int i = 0; i < 6; i++) {
+			_info[i] = parseInt("0x" + _table.substring(i * 5, 5 * (i + 1)));
+		}
+		String[] _calday = new String[24];
+		for (int i = 0; i < 6; i++) {
+			_calday[4*i] = _info[i].toString().substring(0, 1);
+			_calday[4*i+1] = _info[i].toString().substring(1, 3);
+			_calday[4*i+2] = _info[i].toString().substring(3, 4);
+			_calday[4*i+3] = _info[i].toString().substring(4, 6);
+		}
+		return parseInt(_calday[n - 1]);
+	}
+
+	/**
 	 * 传回农历 y年的总天数
 	 * 传回农历 y年的总天数
 	 *
 	 *
 	 * @param y 年
 	 * @param y 年
@@ -324,7 +490,6 @@ public class ChineseDate {
 		return 0;
 		return 0;
 	}
 	}
 
 
-
 	/**
 	/**
 	 * 传回农历 y年m月的总天数
 	 * 传回农历 y年m月的总天数
 	 *
 	 *
@@ -346,5 +511,58 @@ public class ChineseDate {
 		return (int) (lunarInfo[y - 1900] & 0xf);
 		return (int) (lunarInfo[y - 1900] & 0xf);
 	}
 	}
 
 
+	/**
+	 * 通过农历年月日信息 返回公历信息 提供给构造函数
+	 *
+	 * @param chineseYear  农历年
+	 * @param chineseMonth 农历月
+	 * @param chineseDay   农历日
+	 * @param isLeapMonth  传入的月是不是闰月
+	 * @return
+	 */
+	private Integer[] lunar2solar(int chineseYear, int chineseMonth, int chineseDay, boolean isLeapMonth) {
+		//超出了最大极限值
+		if (chineseYear == 2100 && chineseMonth == 12 && chineseDay > 1 || chineseYear == 1900 && chineseMonth == 1 && chineseDay < 31) {
+			return null;
+		}
+		int day = this.monthDays(chineseYear, chineseMonth);
+		int _day = day;
+		if (isLeapMonth) {
+			_day = this.leapDays(chineseYear);
+		}
+		//参数合法性效验
+		if (chineseYear < 1900 || chineseYear > 2100 || chineseDay > _day) {
+			return null;
+		}
+		//计算农历的时间差
+		int offset = 0;
+		for (int i = 1900; i < chineseYear; i++) {
+			offset += this.yearDays(i);
+		}
+		int leap = 0;
+		boolean isAdd = false;
+		for (int i = 1; i < chineseMonth; i++) {
+			leap = this.leapMonth(chineseYear);
+			if (!isAdd) {//处理闰月
+				if (leap <= i && leap > 0) {
+					offset += this.leapDays(chineseYear);
+					isAdd = true;
+				}
+			}
+			offset += this.monthDays(chineseYear, i);
+		}
+		//转换闰月农历 需补充该年闰月的前一个月的时差
+		if (isLeapMonth) {
+			offset += day;
+		}
+		//1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) -2203804800000
+		DateTime date = DateUtil.date(((offset + chineseDay - 31) * 86400000L) - 2203804800000L);
+		int year = date.year();
+		int month = date.month() + 1;
+		int d = date.dayOfMonth();
+		return new Integer[]{year, month, d};
+	}
+
 	// ------------------------------------------------------- private method end
 	// ------------------------------------------------------- private method end
-}
+
+}

+ 14 - 0
hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java

@@ -45,4 +45,18 @@ public class ChineseDateTest {
 		date = new ChineseDate(DateUtil.parseDate("1996-07-15"));
 		date = new ChineseDate(DateUtil.parseDate("1996-07-15"));
 		Assert.assertEquals("丙子鼠年 五月三十", date.toString());
 		Assert.assertEquals("丙子鼠年 五月三十", date.toString());
 	}
 	}
+	@Test
+	public void getCyclicalYMDTest(){
+		//通过公历构建
+		ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("1993-01-06"));
+		String cyclicalYMD = chineseDate.getCyclicalYMD();
+		Assert.assertEquals("壬申年癸丑月丁亥日",cyclicalYMD);
+	}
+	@Test
+	public void getCyclicalYMDTest_2(){
+		//通过农历构建
+		ChineseDate chineseDate = new ChineseDate(1992,12,14);
+		String cyclicalYMD = chineseDate.getCyclicalYMD();
+		Assert.assertEquals("壬申年癸丑月丁亥日",cyclicalYMD);
+	}
 }
 }