From 42ca239a5868871d580c062fed98c39290cc8f21 Mon Sep 17 00:00:00 2001 From: yl-yue Date: Thu, 1 Apr 2021 16:30:47 +0800 Subject: [PATCH 1/7] =?UTF-8?q?1.=20mapToBean()=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E5=B8=83=E5=B0=94=E5=80=BCis=E5=89=8D=E7=BC=80=E7=9A=84?= =?UTF-8?q?=E8=AF=86=E5=88=AB=202.=20=E6=B7=BB=E5=8A=A0=E7=9B=B8=E5=BA=94?= =?UTF-8?q?=E7=9A=84=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../copier/provider/MapValueProvider.java | 46 +++++++++++++++---- .../cn/hutool/core/bean/BeanUtilTest.java | 18 +++++--- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/MapValueProvider.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/MapValueProvider.java index 16c1f3d74..284858fe2 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/MapValueProvider.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/MapValueProvider.java @@ -50,23 +50,49 @@ public class MapValueProvider implements ValueProvider { @Override public Object value(String key, Type valueType) { - Object value = map.get(key); - if (null == value) { - //检查下划线模式 - value = map.get(StrUtil.toUnderlineCase(key)); - } - + Object value = map.get(getKey(key, valueType)); return Convert.convertWithCheck(valueType, value, null, this.ignoreError); } @Override public boolean containsKey(String key) { + return map.containsKey(getKey(key, null)); + } + + /** + * 获得map中可能包含的key + * + * @param key map中可能包含的key + * @param valueType 值类型,用于判断是否为Boolean,可以为null + * @return map中可能包含的key + */ + private String getKey(String key, Type valueType) { if (map.containsKey(key)) { - return true; - } else { - //检查下划线模式 - return map.containsKey(StrUtil.toUnderlineCase(key)); + return key; } + + //检查下划线模式 + String containKey = StrUtil.toUnderlineCase(key); + if (map.containsKey(containKey)) { + return containKey; + } + + //检查boolean类型 + if (null == valueType || Boolean.class == valueType || boolean.class == valueType) { + //boolean类型字段字段名支持两种方式 + containKey = StrUtil.upperFirstAndAddPre(key, "is"); + if (map.containsKey(containKey)) { + return containKey; + } + + //检查下划线模式 + containKey = StrUtil.toUnderlineCase(containKey); + if (map.containsKey(containKey)) { + return containKey; + } + } + + return key; } } diff --git a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java index 209e4dba5..2c3621871 100644 --- a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java @@ -10,6 +10,7 @@ import cn.hutool.core.util.StrUtil; import lombok.Data; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import org.junit.Assert; import org.junit.Test; @@ -18,13 +19,7 @@ import java.io.Serializable; import java.lang.reflect.Type; import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; /** * Bean工具单元测试 @@ -201,6 +196,8 @@ public class BeanUtilTest { person.setName("测试A11"); person.setSubName("sub名字"); person.setSlow(true); + person.setBooleana(true); + person.setBooleanb(true); Map map = BeanUtil.beanToMap(person); Assert.assertEquals("sub名字", map.get("aliasSubName")); @@ -211,9 +208,13 @@ public class BeanUtilTest { Map map = MapUtil.newHashMap(); map.put("aliasSubName", "sub名字"); map.put("slow", true); + map.put("is_booleana", "1"); + map.put("is_booleanb", true); final SubPersonWithAlias subPersonWithAlias = BeanUtil.toBean(map, SubPersonWithAlias.class); Assert.assertEquals("sub名字", subPersonWithAlias.getSubName()); + Assert.assertTrue(subPersonWithAlias.isBooleana()); + Assert.assertEquals(true, subPersonWithAlias.getBooleanb()); } @Test @@ -360,11 +361,14 @@ public class BeanUtilTest { @Getter @Setter + @ToString public static class SubPersonWithAlias extends Person { // boolean参数值非isXXX形式 @Alias("aliasSubName") private String subName; private Boolean slow; + private boolean booleana; + private Boolean booleanb; } @Getter From 6e6aa91a903e8b45ebb5bf0588db893c67e90e72 Mon Sep 17 00:00:00 2001 From: Zhu Kaixiao <3617246657@qq.com> Date: Fri, 2 Apr 2021 15:15:46 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E8=8E=B7=E5=8F=96=E8=8A=82=E6=B0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/hutool/core/date/ChineseDate.java | 16 +- .../hutool/core/date/chinese/SolarTerms.java | 198 +++++++++++++++++- .../core/date/chinese/SolarTermsTest.java | 80 +++++++ 3 files changed, 288 insertions(+), 6 deletions(-) create mode 100644 hutool-core/src/test/java/cn/hutool/core/date/chinese/SolarTermsTest.java diff --git a/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java b/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java index 454e6c197..017f4b473 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java @@ -1,10 +1,7 @@ package cn.hutool.core.date; import cn.hutool.core.convert.NumberChineseFormatter; -import cn.hutool.core.date.chinese.ChineseMonth; -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.date.chinese.*; import cn.hutool.core.util.StrUtil; import java.util.Date; @@ -264,6 +261,15 @@ public class ChineseDate { return null; } + + /** + * 获得节气 + * @return 获得节气 + */ + public String getTerm() { + return SolarTerms.getTerm(gyear, gmonth, gday); + } + /** * 转换为标准的日期格式来表示农历日期,例如2020-01-13 * @@ -347,4 +353,4 @@ public class ChineseDate { // ------------------------------------------------------- private method end -} \ No newline at end of file +} diff --git a/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java b/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java index 597e60bc2..84d65671a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java @@ -1,15 +1,132 @@ 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 java.time.LocalDate; +import java.util.Date; + /** * 24节气相关信息 * - * @author looly + * @author looly, zak * @since 5.4.1 */ 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]); } + + + /** + * 根据日期获取节气 + * @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节气日期速查表 * 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js diff --git a/hutool-core/src/test/java/cn/hutool/core/date/chinese/SolarTermsTest.java b/hutool-core/src/test/java/cn/hutool/core/date/chinese/SolarTermsTest.java new file mode 100644 index 000000000..be8b2b9c7 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/date/chinese/SolarTermsTest.java @@ -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))); + } +} From d244650ebc09c24ce60f3f93a8ef35a68de95205 Mon Sep 17 00:00:00 2001 From: Zhu Kaixiao <3617246657@qq.com> Date: Fri, 2 Apr 2021 15:27:13 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/hutool/core/date/chinese/SolarTerms.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java b/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java index 84d65671a..28754c08c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java @@ -166,7 +166,7 @@ public class SolarTerms { */ public static String getTerm(Date date) { final DateTime dt = DateUtil.date(date); - return getTerm(dt.year(), dt.month() + 1, dt.dayOfMonth()); + return getTerm0(dt.year(), dt.month() + 1, dt.dayOfMonth()); } From a616903de1d1e3f4d938215590fce241339caa05 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 2 Apr 2021 18:54:05 +0800 Subject: [PATCH 4/7] fix bug --- CHANGELOG.md | 4 +++- hutool-core/src/main/java/cn/hutool/core/lang/Validator.java | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58a5de0e6..1cee76d7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,14 @@ ------------------------------------------------------------------------------------------------------------- -# 5.6.3 (2021-03-31) +# 5.6.3 (2021-04-02) ### 新特性 * 【core 】 修改数字转换的实现,增加按照指定端序转换(pr#1492@Github) * 【core 】 修改拆分byte数组时最后一组长度的规则(pr#1494@Github) + ### Bug修复 +* 【core 】 修复Validator.isUrl()传空返回true(issue#I3ETTY@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java b/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java index bca1d0ae5..cde7cb4ab 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java @@ -951,6 +951,9 @@ public class Validator { * @return 是否为URL */ public static boolean isUrl(CharSequence value) { + if(StrUtil.isBlank(value)){ + return false; + } try { new java.net.URL(StrUtil.str(value)); } catch (MalformedURLException e) { From 4865b10d3b1c51cab31816b8fda10f3088ddf86d Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 2 Apr 2021 19:41:02 +0800 Subject: [PATCH 5/7] add term --- CHANGELOG.md | 1 + .../java/cn/hutool/core/date/ChineseDate.java | 7 +- .../hutool/core/date/chinese/SolarTerms.java | 337 ++++++------------ .../core/date/chinese/SolarTermsTest.java | 137 ++++--- 4 files changed, 205 insertions(+), 277 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cee76d7d..c393aeb89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### 新特性 * 【core 】 修改数字转换的实现,增加按照指定端序转换(pr#1492@Github) * 【core 】 修改拆分byte数组时最后一组长度的规则(pr#1494@Github) +* 【core 】 新增根据日期获取节气(pr#1496@Github) ### Bug修复 * 【core 】 修复Validator.isUrl()传空返回true(issue#I3ETTY@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java b/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java index 9ae29ce98..5d4ea75b7 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java @@ -1,7 +1,11 @@ package cn.hutool.core.date; import cn.hutool.core.convert.NumberChineseFormatter; -import cn.hutool.core.date.chinese.*; +import cn.hutool.core.date.chinese.ChineseMonth; +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.date.chinese.SolarTerms; import cn.hutool.core.util.StrUtil; import java.util.Calendar; @@ -328,6 +332,7 @@ public class ChineseDate { /** * 获得节气 * @return 获得节气 + * @since 5.6.3 */ public String getTerm() { return SolarTerms.getTerm(gyear, gmonth, gday); diff --git a/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java b/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java index 28754c08c..13c7c3b83 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/chinese/SolarTerms.java @@ -16,226 +16,6 @@ import java.util.Date; */ 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]; - - - - - - /** - * 根据节气修正干支月 - * - * @param y 月 - * @param n 节气 - * @return 干支月 - */ - public static int getTerm(int y, int n) { - if (y < 1900 || y > 2100) { - return -1; - } - if (n < 1 || n > 24) { - return -1; - } - - String _table = S_TERM_INFO[y - 1900]; - Integer[] _info = new Integer[6]; - for (int i = 0; i < 6; i++) { - _info[i] = NumberUtil.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 NumberUtil.parseInt(_calday[n - 1]); - } - - - - /** - * 根据日期获取节气 - * @param date 日期 - * @return 返回指定日期所处的节气 - */ - public static String getTerm(Date date) { - final DateTime dt = DateUtil.date(date); - return getTerm0(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节气日期速查表 * 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js @@ -308,4 +88,121 @@ public class SolarTerms { "7f0e36665b66a449801e9808297c35", "665f67f0e37f14898082b072297c35", "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e26665b66a449801e9808297c35", "665f67f0e37f1489801eb072297c35", "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722"}; + + /** + * 24节气 + */ + private static final String[] TERMS = { + "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", + "清明", "谷雨", "立夏", "小满", "芒种", "夏至", + "小暑", "大暑", "立秋", "处暑", "白露", "秋分", + "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" + }; + + /** + * 传入公历y年获得该年第n个节气的公历日期 + * + * @param y 公历年(1900-2100) + * @param n 二十四节气中的第几个节气(1~24);从n=1(小寒)算起 + * @return getTerm(1987,3) -》4;意即1987年2月4日立春 + */ + public static int getTerm(int y, int n) { + if (y < 1900 || y > 2100) { + return -1; + } + if (n < 1 || n > 24) { + return -1; + } + + final String _table = S_TERM_INFO[y - 1900]; + Integer[] _info = new Integer[6]; + for (int i = 0; i < 6; i++) { + _info[i] = Integer.parseInt(_table.substring(i * 5, 5 * (i + 1)), 16); + } + 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 NumberUtil.parseInt(_calday[n - 1]); + } + + /** + * 根据日期获取节气 + * @param date 日期 + * @return 返回指定日期所处的节气 + */ + public static String getTerm(Date date) { + final DateTime dt = DateUtil.date(date); + return getTermInternal(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 getTermInternal(date.getYear(), date.getMonthValue(), date.getDayOfMonth()); + } + + /** + * 根据年月日获取节气 + * @param year 公历年 + * @param mouth 公历月,从1开始 + * @param day 公历日,从1开始 + * @return 返回指定年月日所处的节气 + */ + public static String getTerm(int year, int mouth, int day) { + return getTerm(LocalDate.of(year, mouth, day)); + } + + /** + * 根据年月日获取节气, 内部方法,不对月和日做有效校验 + * @param year 年 + * @param mouth 月,从1计数 + * @param day 日,从1计数 + * @return 返回指定年月日所处的节气 + */ + private static String getTermInternal(int year, int mouth, int day) { + if (year < 1900 || year > 2100) { + throw new IllegalArgumentException("只支持1900-2100之间的日期获取节气"); + } + + final String termTable = S_TERM_INFO[year - 1900]; + + // 节气速查表中每5个字符含有4个节气,通过月份直接计算偏移 + final int segment = (mouth + 1) / 2 - 1; + final int termInfo = Integer.parseInt(termTable.substring(segment * 5, (segment + 1) * 5), 16); + final String termInfoStr = String.valueOf(termInfo); + + final String[] segmentTable = new String[24]; + segmentTable[0] = termInfoStr.substring(0, 1); + segmentTable[1] = termInfoStr.substring(1, 3); + segmentTable[2] = termInfoStr.substring(3, 4); + segmentTable[3] = termInfoStr.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]; + } } diff --git a/hutool-core/src/test/java/cn/hutool/core/date/chinese/SolarTermsTest.java b/hutool-core/src/test/java/cn/hutool/core/date/chinese/SolarTermsTest.java index be8b2b9c7..909af0fb2 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/chinese/SolarTermsTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/chinese/SolarTermsTest.java @@ -5,76 +5,101 @@ 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 getTermTest1(){ + final int term = SolarTerms.getTerm(1987, 3); + Assert.assertEquals(4, term); + } @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)); + Assert.assertEquals("冬至", SolarTerms.getTerm(2021, 1, 4)); + + Assert.assertEquals("小寒", SolarTerms.getTerm(2021, 1, 5)); + Assert.assertEquals("小寒", SolarTerms.getTerm(2021, 1, 19)); + + Assert.assertEquals("大寒", SolarTerms.getTerm(2021, 1, 20)); + Assert.assertEquals("大寒", SolarTerms.getTerm(2021, 2, 2)); + + Assert.assertEquals("立春", SolarTerms.getTerm(2021, 2, 3)); + Assert.assertEquals("立春", SolarTerms.getTerm(2021, 2, 17)); + + Assert.assertEquals("雨水", SolarTerms.getTerm(2021, 2, 18)); + Assert.assertEquals("雨水", SolarTerms.getTerm(2021, 3, 4)); + + Assert.assertEquals("惊蛰", SolarTerms.getTerm(2021, 3, 5)); + Assert.assertEquals("惊蛰", SolarTerms.getTerm(2021, 3, 19)); + + Assert.assertEquals("春分", SolarTerms.getTerm(2021, 3, 20)); + Assert.assertEquals("春分", SolarTerms.getTerm(2021, 4, 3)); + + Assert.assertEquals("清明", SolarTerms.getTerm(2021, 4, 4)); + Assert.assertEquals("清明", SolarTerms.getTerm(2021, 4, 10)); + Assert.assertEquals("清明", SolarTerms.getTerm(2021, 4, 19)); + + Assert.assertEquals("谷雨", SolarTerms.getTerm(2021, 4, 20)); + Assert.assertEquals("谷雨", SolarTerms.getTerm(2021, 4, 29)); + Assert.assertEquals("谷雨", SolarTerms.getTerm(2021, 5, 4)); + + Assert.assertEquals("立夏", SolarTerms.getTerm(2021, 5, 5)); + Assert.assertEquals("立夏", SolarTerms.getTerm(2021, 5, 9)); + Assert.assertEquals("立夏", SolarTerms.getTerm(2021, 5, 20)); + + Assert.assertEquals("小满", SolarTerms.getTerm(2021, 5, 21)); + Assert.assertEquals("小满", SolarTerms.getTerm(2021, 6, 4)); + + Assert.assertEquals("芒种", SolarTerms.getTerm(2021, 6, 5)); + Assert.assertEquals("芒种", SolarTerms.getTerm(2021, 6, 20)); + + Assert.assertEquals("夏至", SolarTerms.getTerm(2021, 6, 21)); + Assert.assertEquals("夏至", SolarTerms.getTerm(2021, 7, 6)); + + Assert.assertEquals("小暑", SolarTerms.getTerm(2021, 7, 7)); + Assert.assertEquals("小暑", SolarTerms.getTerm(2021, 7, 21)); + + Assert.assertEquals("大暑", SolarTerms.getTerm(2021, 7, 22)); + Assert.assertEquals("大暑", SolarTerms.getTerm(2021, 8, 6)); + + Assert.assertEquals("立秋", SolarTerms.getTerm(2021, 8, 7)); + + Assert.assertEquals("处暑", SolarTerms.getTerm(2021, 8, 23)); + Assert.assertEquals("处暑", SolarTerms.getTerm(2021, 9, 6)); + + Assert.assertEquals("白露", SolarTerms.getTerm(2021, 9, 7)); + Assert.assertEquals("白露", SolarTerms.getTerm(2021, 9, 22)); + + Assert.assertEquals("秋分", SolarTerms.getTerm(2021, 9, 23)); + Assert.assertEquals("秋分", SolarTerms.getTerm(2021, 10, 7)); + + Assert.assertEquals("寒露", SolarTerms.getTerm(2021, 10, 8)); + Assert.assertEquals("寒露", SolarTerms.getTerm(2021, 10, 22)); + + Assert.assertEquals("霜降", SolarTerms.getTerm(2021, 10, 23)); + Assert.assertEquals("霜降", SolarTerms.getTerm(2021, 11, 6)); + + Assert.assertEquals("立冬", SolarTerms.getTerm(2021, 11, 7)); + Assert.assertEquals("立冬", SolarTerms.getTerm(2021, 11, 21)); + + Assert.assertEquals("小雪", SolarTerms.getTerm(2021, 11, 22)); + Assert.assertEquals("小雪", SolarTerms.getTerm(2021, 12, 6)); + + Assert.assertEquals("大雪", SolarTerms.getTerm(2021, 12, 7)); + Assert.assertEquals("大雪", SolarTerms.getTerm(2021, 12, 20)); + + Assert.assertEquals("冬至", SolarTerms.getTerm(2021, 12, 21)); } @Test public void getTermByDateTest() { - Assert.assertEquals(SolarTerms.CHUN_FEN, SolarTerms.getTerm(DateUtil.parseDate("2021-04-02"))); + Assert.assertEquals("春分", SolarTerms.getTerm(DateUtil.parseDate("2021-04-02"))); } @Test public void getTermByChineseDateTest() { - Assert.assertEquals(SolarTerms.QING_MING, SolarTerms.getTerm(new ChineseDate(2021, 2, 25))); + Assert.assertEquals("清明", SolarTerms.getTerm(new ChineseDate(2021, 2, 25))); } } From 78aaab53bc32d4c130abe1a4752abc9e238c764c Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 3 Apr 2021 10:46:02 +0800 Subject: [PATCH 6/7] add isXXX support --- CHANGELOG.md | 3 +- .../copier/provider/MapValueProvider.java | 41 ++++++++++++------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c393aeb89..e8ded4206 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,13 @@ ------------------------------------------------------------------------------------------------------------- -# 5.6.3 (2021-04-02) +# 5.6.3 (2021-04-03) ### 新特性 * 【core 】 修改数字转换的实现,增加按照指定端序转换(pr#1492@Github) * 【core 】 修改拆分byte数组时最后一组长度的规则(pr#1494@Github) * 【core 】 新增根据日期获取节气(pr#1496@Github) +* 【core 】 mapToBean()添加对布尔值is前缀的识别(pr#294@Gitee) ### Bug修复 * 【core 】 修复Validator.isUrl()传空返回true(issue#I3ETTY@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/MapValueProvider.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/MapValueProvider.java index 284858fe2..7c84e4074 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/MapValueProvider.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/provider/MapValueProvider.java @@ -10,7 +10,14 @@ import java.util.Map; /** * Map值提供者,支持驼峰和下划线的key兼容。
- * 假设目标属性为firstName,则Map中为firstName或first_name都可以对应到值。 + * 假设目标属性为firstName,则Map中以下形式的值都可以对应: + *
    + *
  • firstName
  • + *
  • first_name
  • + *
  • isFirstName(如果为Boolean或boolean类型的值)
  • + *
  • is_first_name(如果为Boolean或boolean类型的值)
  • + *
+ * 为firstName或first_name都可以对应到值。 * * @author looly */ @@ -50,17 +57,22 @@ public class MapValueProvider implements ValueProvider { @Override public Object value(String key, Type valueType) { - Object value = map.get(getKey(key, valueType)); + final String key1 = getKey(key, valueType); + if (null == key1) { + return null; + } + + final Object value = map.get(key1); return Convert.convertWithCheck(valueType, value, null, this.ignoreError); } @Override public boolean containsKey(String key) { - return map.containsKey(getKey(key, null)); + return null != getKey(key, null); } /** - * 获得map中可能包含的key + * 获得map中可能包含的key,不包含返回null * * @param key map中可能包含的key * @param valueType 值类型,用于判断是否为Boolean,可以为null @@ -72,27 +84,26 @@ public class MapValueProvider implements ValueProvider { } //检查下划线模式 - String containKey = StrUtil.toUnderlineCase(key); - if (map.containsKey(containKey)) { - return containKey; + String customKey = StrUtil.toUnderlineCase(key); + if (map.containsKey(customKey)) { + return customKey; } //检查boolean类型 if (null == valueType || Boolean.class == valueType || boolean.class == valueType) { //boolean类型字段字段名支持两种方式 - containKey = StrUtil.upperFirstAndAddPre(key, "is"); - if (map.containsKey(containKey)) { - return containKey; + customKey = StrUtil.upperFirstAndAddPre(key, "is"); + if (map.containsKey(customKey)) { + return customKey; } //检查下划线模式 - containKey = StrUtil.toUnderlineCase(containKey); - if (map.containsKey(containKey)) { - return containKey; + customKey = StrUtil.toUnderlineCase(customKey); + if (map.containsKey(customKey)) { + return customKey; } } - - return key; + return null; } } From d60b315a202c5a9cdb370f53e9a3addfed5ea17c Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 4 Apr 2021 12:12:53 +0800 Subject: [PATCH 7/7] fix bug --- CHANGELOG.md | 3 ++- .../java/cn/hutool/db/dialect/DialectFactory.java | 7 +++++++ .../java/cn/hutool/db/dialect/DriverUtilTest.java | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 hutool-db/src/test/java/cn/hutool/db/dialect/DriverUtilTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index e8ded4206..3b93dc404 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.6.3 (2021-04-03) +# 5.6.3 (2021-04-04) ### 新特性 * 【core 】 修改数字转换的实现,增加按照指定端序转换(pr#1492@Github) @@ -13,6 +13,7 @@ ### Bug修复 * 【core 】 修复Validator.isUrl()传空返回true(issue#I3ETTY@Gitee) +* 【db 】 修复数据库driver根据url的判断识别错误问题(issue#I3EWBI@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java index 0140ac43c..78e35fa2a 100644 --- a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java @@ -1,6 +1,7 @@ package cn.hutool.db.dialect; import cn.hutool.core.util.ClassLoaderUtil; +import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.db.dialect.impl.AnsiSqlDialect; import cn.hutool.db.dialect.impl.H2Dialect; @@ -115,6 +116,12 @@ public class DialectFactory { // 全部转为小写,忽略大小写 nameContainsProductInfo = StrUtil.cleanBlank(nameContainsProductInfo.toLowerCase()); + // 首先判断是否为标准的JDBC URL,截取jdbc:xxxx:中间部分 + final String name = ReUtil.getGroup1("jdbc:(.*?):", nameContainsProductInfo); + if(StrUtil.isNotBlank(name)){ + nameContainsProductInfo = name; + } + String driver = null; if (nameContainsProductInfo.contains("mysql")) { driver = ClassLoaderUtil.isPresent(DRIVER_MYSQL_V6) ? DRIVER_MYSQL_V6 : DRIVER_MYSQL; diff --git a/hutool-db/src/test/java/cn/hutool/db/dialect/DriverUtilTest.java b/hutool-db/src/test/java/cn/hutool/db/dialect/DriverUtilTest.java new file mode 100644 index 000000000..7dacba36a --- /dev/null +++ b/hutool-db/src/test/java/cn/hutool/db/dialect/DriverUtilTest.java @@ -0,0 +1,14 @@ +package cn.hutool.db.dialect; + +import org.junit.Assert; +import org.junit.Test; + +public class DriverUtilTest { + + @Test + public void identifyDriverTest(){ + String url = "jdbc:h2:file:./db/test;AUTO_SERVER=TRUE;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL"; + String driver = DriverUtil.identifyDriver(url); // driver 返回 mysql 的 driver + Assert.assertEquals("org.h2.Driver", driver); + } +}