mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
新增根据日期获取节气
This commit is contained in:
parent
47134c0536
commit
6e6aa91a90
@ -1,10 +1,7 @@
|
|||||||
package cn.hutool.core.date;
|
package cn.hutool.core.date;
|
||||||
|
|
||||||
import cn.hutool.core.convert.NumberChineseFormatter;
|
import cn.hutool.core.convert.NumberChineseFormatter;
|
||||||
import cn.hutool.core.date.chinese.ChineseMonth;
|
import cn.hutool.core.date.chinese.*;
|
||||||
import cn.hutool.core.date.chinese.GanZhi;
|
|
||||||
import cn.hutool.core.date.chinese.LunarFestival;
|
|
||||||
import cn.hutool.core.date.chinese.LunarInfo;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -264,6 +261,15 @@ public class ChineseDate {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得节气
|
||||||
|
* @return 获得节气
|
||||||
|
*/
|
||||||
|
public String getTerm() {
|
||||||
|
return SolarTerms.getTerm(gyear, gmonth, gday);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为标准的日期格式来表示农历日期,例如2020-01-13
|
* 转换为标准的日期格式来表示农历日期,例如2020-01-13
|
||||||
*
|
*
|
||||||
@ -347,4 +353,4 @@ public class ChineseDate {
|
|||||||
|
|
||||||
// ------------------------------------------------------- private method end
|
// ------------------------------------------------------- private method end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,132 @@
|
|||||||
package cn.hutool.core.date.chinese;
|
package cn.hutool.core.date.chinese;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.ChineseDate;
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 24节气相关信息
|
* 24节气相关信息
|
||||||
*
|
*
|
||||||
* @author looly
|
* @author looly, zak
|
||||||
* @since 5.4.1
|
* @since 5.4.1
|
||||||
*/
|
*/
|
||||||
public class SolarTerms {
|
public class SolarTerms {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 24节气
|
||||||
|
*/
|
||||||
|
public static final String[] TERMS = {
|
||||||
|
"小寒", "大寒", "立春", "雨水", "惊蛰", "春分",
|
||||||
|
"清明", "谷雨", "立夏", "小满", "芒种", "夏至",
|
||||||
|
"小暑", "大暑", "立秋", "处暑", "白露", "秋分",
|
||||||
|
"寒露", "霜降", "立冬", "小雪", "大雪", "冬至"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小寒
|
||||||
|
*/
|
||||||
|
public static final String XIAO_HAN = TERMS[0];
|
||||||
|
/**
|
||||||
|
* 大寒
|
||||||
|
*/
|
||||||
|
public static final String DA_HAN = TERMS[1];
|
||||||
|
/**
|
||||||
|
* 立春
|
||||||
|
*/
|
||||||
|
public static final String LI_CHUN = TERMS[2];
|
||||||
|
/**
|
||||||
|
* 雨水
|
||||||
|
*/
|
||||||
|
public static final String YU_SHUI = TERMS[3];
|
||||||
|
/**
|
||||||
|
* 惊蛰
|
||||||
|
*/
|
||||||
|
public static final String JING_ZHE = TERMS[4];
|
||||||
|
/**
|
||||||
|
* 春分
|
||||||
|
*/
|
||||||
|
public static final String CHUN_FEN = TERMS[5];
|
||||||
|
/**
|
||||||
|
* 清明
|
||||||
|
*/
|
||||||
|
public static final String QING_MING = TERMS[6];
|
||||||
|
/**
|
||||||
|
* 谷雨
|
||||||
|
*/
|
||||||
|
public static final String GU_YU = TERMS[7];
|
||||||
|
/**
|
||||||
|
* 立夏
|
||||||
|
*/
|
||||||
|
public static final String LI_XIA = TERMS[8];
|
||||||
|
/**
|
||||||
|
* 小满
|
||||||
|
*/
|
||||||
|
public static final String XIAO_MAN = TERMS[9];
|
||||||
|
/**
|
||||||
|
* 芒种
|
||||||
|
*/
|
||||||
|
public static final String MANG_ZHONG = TERMS[10];
|
||||||
|
/**
|
||||||
|
* 夏至
|
||||||
|
*/
|
||||||
|
public static final String XIA_ZHI = TERMS[11];
|
||||||
|
/**
|
||||||
|
* 小暑
|
||||||
|
*/
|
||||||
|
public static final String XIAO_SHU = TERMS[12];
|
||||||
|
/**
|
||||||
|
* 大暑
|
||||||
|
*/
|
||||||
|
public static final String DA_SHU = TERMS[13];
|
||||||
|
/**
|
||||||
|
* 立秋
|
||||||
|
*/
|
||||||
|
public static final String LI_QIU = TERMS[14];
|
||||||
|
/**
|
||||||
|
* 处暑
|
||||||
|
*/
|
||||||
|
public static final String CHU_SHU = TERMS[15];
|
||||||
|
/**
|
||||||
|
* 白露
|
||||||
|
*/
|
||||||
|
public static final String BAI_LU = TERMS[16];
|
||||||
|
/**
|
||||||
|
* 秋分
|
||||||
|
*/
|
||||||
|
public static final String QIU_FEN = TERMS[17];
|
||||||
|
/**
|
||||||
|
* 寒露
|
||||||
|
*/
|
||||||
|
public static final String HAN_LU = TERMS[18];
|
||||||
|
/**
|
||||||
|
* 霜降
|
||||||
|
*/
|
||||||
|
public static final String SHUANG_JIANG = TERMS[19];
|
||||||
|
/**
|
||||||
|
* 立冬
|
||||||
|
*/
|
||||||
|
public static final String LI_DONG = TERMS[20];
|
||||||
|
/**
|
||||||
|
* 小雪
|
||||||
|
*/
|
||||||
|
public static final String XIAO_XUE = TERMS[21];
|
||||||
|
/**
|
||||||
|
* 大雪
|
||||||
|
*/
|
||||||
|
public static final String DA_XUE = TERMS[22];
|
||||||
|
/**
|
||||||
|
* 冬至
|
||||||
|
*/
|
||||||
|
public static final String DONG_ZHI = TERMS[23];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据节气修正干支月
|
* 根据节气修正干支月
|
||||||
*
|
*
|
||||||
@ -40,6 +157,85 @@ public class SolarTerms {
|
|||||||
return NumberUtil.parseInt(_calday[n - 1]);
|
return NumberUtil.parseInt(_calday[n - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据日期获取节气
|
||||||
|
* @param date 日期
|
||||||
|
* @return 返回指定日期所处的节气
|
||||||
|
*/
|
||||||
|
public static String getTerm(Date date) {
|
||||||
|
final DateTime dt = DateUtil.date(date);
|
||||||
|
return getTerm(dt.year(), dt.month() + 1, dt.dayOfMonth());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据农历日期获取节气
|
||||||
|
* @param chineseDate 农历日期
|
||||||
|
* @return 返回指定日期所处的节气
|
||||||
|
*/
|
||||||
|
public static String getTerm(ChineseDate chineseDate) {
|
||||||
|
return chineseDate.getTerm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据日期获取节气
|
||||||
|
* @param date 日期
|
||||||
|
* @return 返回指定日期所处的节气
|
||||||
|
*/
|
||||||
|
public static String getTerm(LocalDate date) {
|
||||||
|
return getTerm0(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据年月日获取节气
|
||||||
|
* @param year 年
|
||||||
|
* @param mouth 月
|
||||||
|
* @param day 日
|
||||||
|
* @return 返回指定年月日所处的节气
|
||||||
|
*/
|
||||||
|
public static String getTerm(int year, int mouth, int day) {
|
||||||
|
return getTerm(LocalDate.of(year, mouth, day));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据年月日获取节气, 内部方法,不对月和日做有效校验
|
||||||
|
* @param year 年
|
||||||
|
* @param mouth 月
|
||||||
|
* @param day 日
|
||||||
|
* @return 返回指定年月日所处的节气
|
||||||
|
*/
|
||||||
|
static String getTerm0(int year, int mouth, int day) {
|
||||||
|
if (year < 1900 || year > 2100) {
|
||||||
|
throw new IllegalArgumentException("只支持1900-2100之间的日期获取节气");
|
||||||
|
}
|
||||||
|
|
||||||
|
String termTable = S_TERM_INFO[year - 1900];
|
||||||
|
|
||||||
|
// 节气速查表中每5个字符含有4个节气,通过月份直接计算偏移
|
||||||
|
int segment = (mouth + 1) / 2 - 1;
|
||||||
|
int termInfo = NumberUtil.parseInt("0x" + termTable.substring(segment * 5, (segment + 1) * 5));
|
||||||
|
|
||||||
|
String[] segmentTable = new String[24];
|
||||||
|
segmentTable[0] = String.valueOf(termInfo).substring(0, 1);
|
||||||
|
segmentTable[1] = String.valueOf(termInfo).substring(1, 3);
|
||||||
|
segmentTable[2] = String.valueOf(termInfo).substring(3, 4);
|
||||||
|
segmentTable[3] = String.valueOf(termInfo).substring(4, 6);
|
||||||
|
|
||||||
|
// 奇数月份的节气在前2个,偶数月份的节气在后两个
|
||||||
|
int segmentOffset = (mouth & 1) == 1 ? 0 : 2;
|
||||||
|
if (day < NumberUtil.parseInt(segmentTable[segmentOffset])) {
|
||||||
|
int idx = segment * 4 + segmentOffset - 1;
|
||||||
|
return TERMS[idx < 0 ? 23 : idx];
|
||||||
|
}
|
||||||
|
if(day >= NumberUtil.parseInt(segmentTable[segmentOffset + 1])) {
|
||||||
|
return TERMS[segment * 4 + segmentOffset + 1];
|
||||||
|
}
|
||||||
|
return TERMS[segment * 4 + segmentOffset];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1900-2100各年的24节气日期速查表
|
* 1900-2100各年的24节气日期速查表
|
||||||
* 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js
|
* 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
package cn.hutool.core.date.chinese;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.ChineseDate;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class SolarTermsTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getTermTest() {
|
||||||
|
Assert.assertEquals(SolarTerms.DONG_ZHI, SolarTerms.getTerm(2021, 1, 4));
|
||||||
|
Assert.assertEquals(SolarTerms.XIAO_HAN, SolarTerms.getTerm(2021, 1, 5));
|
||||||
|
Assert.assertEquals(SolarTerms.XIAO_HAN, SolarTerms.getTerm(2021, 1, 19));
|
||||||
|
Assert.assertEquals(SolarTerms.DA_HAN, SolarTerms.getTerm(2021, 1, 20));
|
||||||
|
Assert.assertEquals(SolarTerms.DA_HAN, SolarTerms.getTerm(2021, 2, 2));
|
||||||
|
Assert.assertEquals(SolarTerms.LI_CHUN, SolarTerms.getTerm(2021, 2, 3));
|
||||||
|
Assert.assertEquals(SolarTerms.LI_CHUN, SolarTerms.getTerm(2021, 2, 17));
|
||||||
|
Assert.assertEquals(SolarTerms.YU_SHUI, SolarTerms.getTerm(2021, 2, 18));
|
||||||
|
Assert.assertEquals(SolarTerms.YU_SHUI, SolarTerms.getTerm(2021, 3, 4));
|
||||||
|
Assert.assertEquals(SolarTerms.JING_ZHE, SolarTerms.getTerm(2021, 3, 5));
|
||||||
|
Assert.assertEquals(SolarTerms.JING_ZHE, SolarTerms.getTerm(2021, 3, 19));
|
||||||
|
Assert.assertEquals(SolarTerms.CHUN_FEN, SolarTerms.getTerm(2021, 3, 20));
|
||||||
|
Assert.assertEquals(SolarTerms.CHUN_FEN, SolarTerms.getTerm(2021, 4, 3));
|
||||||
|
Assert.assertEquals(SolarTerms.QING_MING, SolarTerms.getTerm(2021, 4, 4));
|
||||||
|
Assert.assertEquals(SolarTerms.QING_MING, SolarTerms.getTerm(2021, 4, 10));
|
||||||
|
Assert.assertEquals(SolarTerms.QING_MING, SolarTerms.getTerm(2021, 4, 19));
|
||||||
|
Assert.assertEquals(SolarTerms.GU_YU, SolarTerms.getTerm(2021, 4, 20));
|
||||||
|
Assert.assertEquals(SolarTerms.GU_YU, SolarTerms.getTerm(2021, 4, 29));
|
||||||
|
Assert.assertEquals(SolarTerms.GU_YU, SolarTerms.getTerm(2021, 5, 4));
|
||||||
|
Assert.assertEquals(SolarTerms.LI_XIA, SolarTerms.getTerm(2021, 5, 5));
|
||||||
|
Assert.assertEquals(SolarTerms.LI_XIA, SolarTerms.getTerm(2021, 5, 9));
|
||||||
|
Assert.assertEquals(SolarTerms.LI_XIA, SolarTerms.getTerm(2021, 5, 20));
|
||||||
|
Assert.assertEquals(SolarTerms.XIAO_MAN, SolarTerms.getTerm(2021, 5, 21));
|
||||||
|
Assert.assertEquals(SolarTerms.XIAO_MAN, SolarTerms.getTerm(2021, 6, 4));
|
||||||
|
Assert.assertEquals(SolarTerms.MANG_ZHONG, SolarTerms.getTerm(2021, 6, 5));
|
||||||
|
Assert.assertEquals(SolarTerms.MANG_ZHONG, SolarTerms.getTerm(2021, 6, 20));
|
||||||
|
Assert.assertEquals(SolarTerms.XIA_ZHI, SolarTerms.getTerm(2021, 6, 21));
|
||||||
|
Assert.assertEquals(SolarTerms.XIA_ZHI, SolarTerms.getTerm(2021, 7, 6));
|
||||||
|
Assert.assertEquals(SolarTerms.XIAO_SHU, SolarTerms.getTerm(2021, 7, 7));
|
||||||
|
Assert.assertEquals(SolarTerms.XIAO_SHU, SolarTerms.getTerm(2021, 7, 21));
|
||||||
|
Assert.assertEquals(SolarTerms.DA_SHU, SolarTerms.getTerm(2021, 7, 22));
|
||||||
|
Assert.assertEquals(SolarTerms.DA_SHU, SolarTerms.getTerm(2021, 8, 6));
|
||||||
|
Assert.assertEquals(SolarTerms.LI_QIU, SolarTerms.getTerm(2021, 8, 7));
|
||||||
|
Assert.assertEquals(SolarTerms.CHU_SHU, SolarTerms.getTerm(2021, 8, 23));
|
||||||
|
Assert.assertEquals(SolarTerms.CHU_SHU, SolarTerms.getTerm(2021, 9, 6));
|
||||||
|
Assert.assertEquals(SolarTerms.BAI_LU, SolarTerms.getTerm(2021, 9, 7));
|
||||||
|
Assert.assertEquals(SolarTerms.BAI_LU, SolarTerms.getTerm(2021, 9, 22));
|
||||||
|
Assert.assertEquals(SolarTerms.QIU_FEN, SolarTerms.getTerm(2021, 9, 23));
|
||||||
|
Assert.assertEquals(SolarTerms.QIU_FEN, SolarTerms.getTerm(2021, 10, 7));
|
||||||
|
Assert.assertEquals(SolarTerms.HAN_LU, SolarTerms.getTerm(2021, 10, 8));
|
||||||
|
Assert.assertEquals(SolarTerms.HAN_LU, SolarTerms.getTerm(2021, 10, 22));
|
||||||
|
Assert.assertEquals(SolarTerms.SHUANG_JIANG, SolarTerms.getTerm(2021, 10, 23));
|
||||||
|
Assert.assertEquals(SolarTerms.SHUANG_JIANG, SolarTerms.getTerm(2021, 11, 6));
|
||||||
|
Assert.assertEquals(SolarTerms.LI_DONG, SolarTerms.getTerm(2021, 11, 7));
|
||||||
|
Assert.assertEquals(SolarTerms.LI_DONG, SolarTerms.getTerm(2021, 11, 21));
|
||||||
|
Assert.assertEquals(SolarTerms.XIAO_XUE, SolarTerms.getTerm(2021, 11, 22));
|
||||||
|
Assert.assertEquals(SolarTerms.XIAO_XUE, SolarTerms.getTerm(2021, 12, 6));
|
||||||
|
Assert.assertEquals(SolarTerms.DA_XUE, SolarTerms.getTerm(2021, 12, 7));
|
||||||
|
Assert.assertEquals(SolarTerms.DA_XUE, SolarTerms.getTerm(2021, 12, 20));
|
||||||
|
Assert.assertEquals(SolarTerms.DONG_ZHI, SolarTerms.getTerm(2021, 12, 21));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getTermByDateTest() {
|
||||||
|
Assert.assertEquals(SolarTerms.CHUN_FEN, SolarTerms.getTerm(DateUtil.parseDate("2021-04-02")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getTermByChineseDateTest() {
|
||||||
|
Assert.assertEquals(SolarTerms.QING_MING, SolarTerms.getTerm(new ChineseDate(2021, 2, 25)));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user