mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
Merge remote-tracking branch 'origin/v5-dev' into v5-dev
This commit is contained in:
@@ -143,7 +143,7 @@ public class CombinationAnnotationElement implements AnnotatedElement, Serializa
|
||||
annotationType = annotation.annotationType();
|
||||
// issue#I5FQGW@Gitee:跳过元注解和已经处理过的注解,防止递归调用
|
||||
if (AnnotationUtil.isNotJdkMateAnnotation(annotationType)
|
||||
&& false == declaredAnnotationMap.containsKey(annotationType)) {
|
||||
&& false == annotationMap.containsKey(annotationType)) {
|
||||
if(test(annotation)){
|
||||
annotationMap.put(annotationType, annotation);
|
||||
}
|
||||
|
@@ -2,8 +2,10 @@ package cn.hutool.core.collection;
|
||||
|
||||
import cn.hutool.core.comparator.PinyinComparator;
|
||||
import cn.hutool.core.comparator.PropertyComparator;
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.Matcher;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.PageUtil;
|
||||
@@ -431,6 +433,8 @@ public class ListUtil {
|
||||
if (index < size) {
|
||||
list.set(index, element);
|
||||
} else {
|
||||
// issue#3286, 增加安全检查,最多增加10倍
|
||||
Validator.checkIndexLimit(index, list.size());
|
||||
for (int i = size; i < index; i++) {
|
||||
list.add(paddingElement);
|
||||
}
|
||||
|
@@ -193,6 +193,20 @@ public class ConverterRegistry implements Serializable {
|
||||
type = defaultValue.getClass();
|
||||
}
|
||||
|
||||
// issue#I7WJHH,Opt和Optional处理
|
||||
if (value instanceof Opt) {
|
||||
value = ((Opt<T>) value).get();
|
||||
if (ObjUtil.isNull(value)) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
if (value instanceof Optional) {
|
||||
value = ((Optional<T>) value).orElse(null);
|
||||
if (ObjUtil.isNull(value)) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (type instanceof TypeReference) {
|
||||
type = ((TypeReference<?>) type).getType();
|
||||
}
|
||||
|
@@ -629,7 +629,12 @@ public class CalendarUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算相对于dateToCompare的年龄,常用于计算指定生日在某年的年龄
|
||||
* 计算相对于dateToCompare的年龄,常用于计算指定生日在某年的年龄<br>
|
||||
* 按照《最高人民法院关于审理未成年人刑事案件具体应用法律若干问题的解释》第二条规定刑法第十七条规定的“周岁”,按照公历的年、月、日计算,从周岁生日的第二天起算。
|
||||
* <ul>
|
||||
* <li>2022-03-01出生,则相对2023-03-01,周岁为0,相对于2023-03-02才是1岁。</li>
|
||||
* <li>1999-02-28出生,则相对2000-02-29,周岁为1</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param birthday 生日
|
||||
* @param dateToCompare 需要对比的日期
|
||||
@@ -646,22 +651,22 @@ public class CalendarUtil {
|
||||
final int year = cal.get(Calendar.YEAR);
|
||||
final int month = cal.get(Calendar.MONTH);
|
||||
final int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
|
||||
final boolean isLastDayOfMonth = dayOfMonth == cal.getActualMaximum(Calendar.DAY_OF_MONTH);
|
||||
|
||||
// 复用cal
|
||||
cal.setTimeInMillis(birthday);
|
||||
int age = year - cal.get(Calendar.YEAR);
|
||||
|
||||
final int monthBirth = cal.get(Calendar.MONTH);
|
||||
|
||||
//当前日期,则为0岁
|
||||
if (age == 0){
|
||||
return 0;
|
||||
} else if (month == monthBirth) {
|
||||
}
|
||||
|
||||
final int monthBirth = cal.get(Calendar.MONTH);
|
||||
if (month == monthBirth) {
|
||||
final int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
|
||||
final boolean isLastDayOfMonthBirth = dayOfMonthBirth == cal.getActualMaximum(Calendar.DAY_OF_MONTH);
|
||||
if ((false == isLastDayOfMonth || false == isLastDayOfMonthBirth) && dayOfMonth <= dayOfMonthBirth) {
|
||||
// 如果生日在当月,但是未超过生日当天的日期,年龄减一
|
||||
// issue#I6E6ZG,法定生日当天不算年龄,从第二天开始计算
|
||||
if (dayOfMonth <= dayOfMonthBirth) {
|
||||
// 如果生日在当月,但是未达到生日当天的日期,年龄减一
|
||||
age--;
|
||||
}
|
||||
} else if (month < monthBirth) {
|
||||
|
@@ -97,7 +97,7 @@ public class ConsoleTable {
|
||||
*/
|
||||
private void fillColumns(List<String> l, String[] columns) {
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
String column = columns[i];
|
||||
String column = StrUtil.toString(columns[i]);
|
||||
if (isSBCMode) {
|
||||
column = Convert.toSBC(column);
|
||||
}
|
||||
|
@@ -1257,4 +1257,23 @@ public class Validator {
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查给定的index是否超出长度限制,默认检查超出倍数(10倍),此方法主要用于内部,检查包括:
|
||||
* <ul>
|
||||
* <li>数组调用setOrPadding时,最多允许padding的长度</li>
|
||||
* <li>List调用setOrPadding时,最多允许padding的长度</li>
|
||||
* <li>JSONArray调用setOrPadding时,最多允许padding的长度</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param index 索引
|
||||
* @param size 数组、列表长度
|
||||
* @since 5.8.22
|
||||
*/
|
||||
public static void checkIndexLimit(final int index, final int size) {
|
||||
// issue#3286, 增加安全检查,最多增加10倍
|
||||
if (index > (size + 1) * 10) {
|
||||
throw new ValidateException("Index [{}] is too large for size: [{}]", index, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -407,7 +407,7 @@ public class Ipv4Util {
|
||||
*/
|
||||
public static Long getEndIpLong(String ip, int maskBit) {
|
||||
return getBeginIpLong(ip, maskBit)
|
||||
+ ~ipv4ToLong(getMaskByMaskBit(maskBit));
|
||||
+ (0xffffffffL & ~ipv4ToLong(getMaskByMaskBit(maskBit)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1064,7 +1064,7 @@ public class CharSequenceUtil {
|
||||
return null;
|
||||
}
|
||||
for (CharSequence checkStr : testStrs) {
|
||||
if (str.toString().contains(checkStr)) {
|
||||
if (null != checkStr && str.toString().contains(checkStr)) {
|
||||
return checkStr.toString();
|
||||
}
|
||||
}
|
||||
|
@@ -2948,10 +2948,10 @@ public class NumberUtil {
|
||||
/**
|
||||
* 检查是否为有效的数字<br>
|
||||
* 检查Double和Float是否为无限大,或者Not a Number<br>
|
||||
* 非数字类型和Null将返回true
|
||||
* 非数字类型和Null将返回false
|
||||
*
|
||||
* @param number 被检查类型
|
||||
* @return 检查结果,非数字类型和Null将返回true
|
||||
* @return 检查结果,非数字类型和Null将返回false
|
||||
* @since 4.6.7
|
||||
*/
|
||||
public static boolean isValidNumber(Number number) {
|
||||
|
38
hutool-core/src/test/java/cn/hutool/core/convert/IssueI7WJHHTest.java
Executable file
38
hutool-core/src/test/java/cn/hutool/core/convert/IssueI7WJHHTest.java
Executable file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package cn.hutool.core.convert;
|
||||
|
||||
import cn.hutool.core.lang.Opt;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class IssueI7WJHHTest {
|
||||
|
||||
@Test
|
||||
public void toIntTest() {
|
||||
final Optional<Integer> optional = Optional.of(1);
|
||||
final Integer integer = Convert.toInt(optional);
|
||||
|
||||
Assert.assertEquals(Integer.valueOf(1), integer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toIntTest2() {
|
||||
final Opt<Integer> optional = Opt.of(1);
|
||||
final Integer integer = Convert.toInt(optional);
|
||||
|
||||
Assert.assertEquals(Integer.valueOf(1), integer);
|
||||
}
|
||||
}
|
@@ -868,7 +868,9 @@ public class DateUtilTest {
|
||||
final String d1 = "2000-02-29";
|
||||
final String d2 = "2018-02-28";
|
||||
final int age = DateUtil.age(DateUtil.parseDate(d1), DateUtil.parseDate(d2));
|
||||
Assert.assertEquals(18, age);
|
||||
|
||||
// issue#I6E6ZG,法定生日当天不算年龄,从第二天开始计算
|
||||
Assert.assertEquals(17, age);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@@ -878,6 +880,28 @@ public class DateUtilTest {
|
||||
DateUtil.age(DateUtil.parseDate(d1), DateUtil.parseDate(d2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ageTest3() {
|
||||
// 按照《最高人民法院关于审理未成年人刑事案件具体应用法律若干问题的解释》第二条规定刑法第十七条规定的“周岁”,按照公历的年、月、日计算,从周岁生日的第二天起算。
|
||||
// 那我们认为就算当年是闰年,29日也算周岁生日的第二天,可以算作一岁
|
||||
final String d1 = "1998-02-28";
|
||||
final String d2 = "2000-02-29";
|
||||
final int age = DateUtil.age(DateUtil.parse(d1), DateUtil.parse(d2));
|
||||
// issue#I6E6ZG,法定生日当天不算年龄,从第二天开始计算
|
||||
Assert.assertEquals(2, age);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ageTest4() {
|
||||
// 按照《最高人民法院关于审理未成年人刑事案件具体应用法律若干问题的解释》第二条规定刑法第十七条规定的“周岁”,按照公历的年、月、日计算,从周岁生日的第二天起算。
|
||||
// 那我们认为就算当年是闰年,29日也算周岁生日的第二天,可以算作一岁
|
||||
final String d1 = "1999-02-28";
|
||||
final String d2 = "2000-02-29";
|
||||
final int age = DateUtil.age(DateUtil.parse(d1), DateUtil.parse(d2));
|
||||
// issue#I6E6ZG,法定生日当天不算年龄,从第二天开始计算
|
||||
Assert.assertEquals(1, age);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isExpiredTest() {
|
||||
final DateTime startDate = DateUtil.parse("2019-12-01 17:02:30");
|
||||
|
27
hutool-core/src/test/java/cn/hutool/core/date/IssueI7XMYWTest.java
Executable file
27
hutool-core/src/test/java/cn/hutool/core/date/IssueI7XMYWTest.java
Executable file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package cn.hutool.core.date;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class IssueI7XMYWTest {
|
||||
@Test
|
||||
public void ageTest() {
|
||||
DateTime date1 = DateUtil.parse("2023-08-31");
|
||||
Assert.assertEquals(49, DateUtil.age(DateUtil.parse("1973-08-31"), date1));
|
||||
|
||||
date1 = DateUtil.parse("2023-08-30");
|
||||
Assert.assertEquals(49, DateUtil.age(DateUtil.parse("1973-08-30"), date1));
|
||||
}
|
||||
}
|
@@ -220,6 +220,12 @@ public class NumberUtilTest {
|
||||
Assert.assertEquals("467.81", format);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isValidNumberTest() {
|
||||
boolean validNumber = NumberUtil.isValidNumber(1);
|
||||
Assert.assertTrue(validNumber);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decimalFormatMoneyTest() {
|
||||
final double c = 299792400.543534534;
|
||||
|
@@ -412,6 +412,10 @@ public class StrUtilTest {
|
||||
Assert.assertFalse(containsAny);
|
||||
containsAny = StrUtil.containsAny("aaabbbccc", "d", "c");
|
||||
Assert.assertTrue(containsAny);
|
||||
|
||||
// https://gitee.com/dromara/hutool/issues/I7WSYD
|
||||
containsAny = StrUtil.containsAny("你好啊", "嗯", null);
|
||||
Assert.assertFalse(containsAny);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Reference in New Issue
Block a user