添加了返回干支纪年较为全面的信息方法 getCyclicalYMD() 可返回包括年月日的干支纪年信息

This commit is contained in:
dcbai 2020-08-28 13:24:41 +08:00
parent f49c3cba6e
commit d7175771c4
2 changed files with 261 additions and 29 deletions

View File

@ -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 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,//1900-1909
0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,//1910-1919
0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,//1920-1929
0x06566,0x0d4a0,0x0ea50,0x16a95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939 0x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,//1930-1939
0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,//1940-1949
0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0,//1950-1959
0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,//1960-1969
0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6,//1970-1979
0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,//1980-1989
0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x05ac0,0x0ab60,0x096d5,0x092e0,//1990-1999 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0,//1990-1999
0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,//2000-2009
0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,//2010-2019
0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,//2020-2029
0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,//2030-2039
0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0,//2040-2049
0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0,//2050-2059
0x092e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069 0x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4,//2060-2069
0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0,//2070-2079
0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160,//2080-2089
0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099 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;
} }
/** /**
* 获得农历月份中文例如二月十二月或者润一月 * 获得农历月份中文例如二月十二月或者润一月
* *
@ -269,6 +372,17 @@ public class ChineseDate {
return (cyclicalm(num)); return (cyclicalm(num));
} }
/**
* 干支纪年信息
*
* @return 获得天干地支的年月日信息
*/
public String getCyclicalYMD() {
if (gyear >= 1900 && gmonth > 0 && gday > 0)
return (cyclicalm(gyear, gmonth, gday));
return "";
}
/** /**
* 转换为标准的日期格式来表示农历日期例如2020-01-13 * 转换为标准的日期格式来表示农历日期例如2020-01-13
* *
@ -295,6 +409,58 @@ public class ChineseDate {
return (Gan[num % 10] + Zhi[num % 12]); return (Gan[num % 10] + Zhi[num % 12]);
} }
/**
* 这里同步处理年月日的天干地支信息
*
* @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年的总天数
* *
@ -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
} }

View File

@ -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);
}
} }