diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/data/CIN.java b/hutool-core/src/main/java/org/dromara/hutool/core/data/CIN.java
index 858f52a92..531ec3a27 100755
--- a/hutool-core/src/main/java/org/dromara/hutool/core/data/CIN.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/data/CIN.java
@@ -197,7 +197,12 @@ public class CIN {
}
/**
- * 根据身份编号获取指定日期当时的年龄年龄
+ * 根据身份编号获取指定日期当时的年龄年龄(周岁)
+ * 按照《最高人民法院关于审理未成年人刑事案件具体应用法律若干问题的解释》第二条规定刑法第十七条规定的“周岁”,按照公历的年、月、日计算,从周岁生日的第二天起算。
+ *
+ * - 2022-03-01出生,则相对2023-03-01,周岁为0,相对于2023-03-02才是1岁。
+ * - 1999-02-28出生,则相对2000-02-29,周岁为1
+ *
*
* @param dateToCompare 以此日期为界,计算年龄。
* @return 年龄
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java
index d0012412e..6578240da 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java
@@ -573,7 +573,12 @@ public class CalendarUtil {
}
/**
- * 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄
+ * 计算相对于dateToCompare的年龄,常用于计算指定生日在某年的年龄
+ * 按照《最高人民法院关于审理未成年人刑事案件具体应用法律若干问题的解释》第二条规定刑法第十七条规定的“周岁”,按照公历的年、月、日计算,从周岁生日的第二天起算。
+ *
+ * - 2022-03-01出生,则相对2023-03-01,周岁为0,相对于2023-03-02才是1岁。
+ * - 1999-02-28出生,则相对2000-02-29,周岁为1
+ *
*
* @param birthday 生日
* @param dateToCompare 需要对比的日期
@@ -745,7 +750,12 @@ public class CalendarUtil {
// endregion
/**
- * 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄
+ * 计算相对于dateToCompare的年龄(周岁),常用于计算指定生日在某年的年龄
+ * 按照《最高人民法院关于审理未成年人刑事案件具体应用法律若干问题的解释》第二条规定刑法第十七条规定的“周岁”,按照公历的年、月、日计算,从周岁生日的第二天起算。
+ *
+ * - 2022-03-01出生,则相对2023-03-01,周岁为0,相对于2023-03-02才是1岁。
+ * - 1999-02-28出生,则相对2000-02-29,周岁为1
+ *
*
* @param birthday 生日
* @param dateToCompare 需要对比的日期
@@ -762,8 +772,8 @@ 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);
//当前日期,则为0岁
@@ -773,11 +783,9 @@ public class CalendarUtil {
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);
// issue#I6E6ZG,法定生日当天不算年龄,从第二天开始计算
- if ((!isLastDayOfMonth || !isLastDayOfMonthBirth) && dayOfMonth <= dayOfMonthBirth) {
+ if (dayOfMonth <= dayOfMonthBirth) {
// 如果生日在当月,但是未达到生日当天的日期,年龄减一
age--;
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java
index f31372ed2..bb4ce981e 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java
@@ -1598,7 +1598,12 @@ public class DateUtil extends CalendarUtil {
}
/**
- * 生日转为年龄,计算法定年龄
+ * 生日转为年龄,计算法定年龄(周岁)
+ * 按照《最高人民法院关于审理未成年人刑事案件具体应用法律若干问题的解释》第二条规定刑法第十七条规定的“周岁”,按照公历的年、月、日计算,从周岁生日的第二天起算。
+ *
+ * - 2022-03-01出生,则相对2023-03-01,周岁为0,相对于2023-03-02才是1岁。
+ * - 1999-02-28出生,则相对2000-02-29,周岁为1
+ *
*
* @param birthDay 生日
* @return 年龄
@@ -1618,7 +1623,12 @@ public class DateUtil extends CalendarUtil {
}
/**
- * 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄
+ * 计算相对于dateToCompare的年龄,常用于计算指定生日在某年的年龄
+ * 按照《最高人民法院关于审理未成年人刑事案件具体应用法律若干问题的解释》第二条规定刑法第十七条规定的“周岁”,按照公历的年、月、日计算,从周岁生日的第二天起算。
+ *
+ * - 2022-03-01出生,则相对2023-03-01,周岁为0,相对于2023-03-02才是1岁。
+ * - 1999-02-28出生,则相对2000-02-29,周岁为1
+ *
*
* @param birthday 生日
* @param dateToCompare 需要对比的日期
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/data/IssueI7XMYWTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/data/IssueI7XMYWTest.java
new file mode 100755
index 000000000..e21ec6bc3
--- /dev/null
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/data/IssueI7XMYWTest.java
@@ -0,0 +1,30 @@
+/*
+ * 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:
+ * https://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 org.dromara.hutool.core.data;
+
+import org.dromara.hutool.core.date.DateTime;
+import org.dromara.hutool.core.date.DateUtil;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class IssueI7XMYWTest {
+
+ @Test
+ public void ageTest() {
+ DateTime date1 = DateUtil.parse("2023-08-31");
+ Assertions.assertEquals(49, DateUtil.age(DateUtil.parse("1973-08-31"), date1));
+
+ date1 = DateUtil.parse("2023-08-30");
+ Assertions.assertEquals(49, DateUtil.age(DateUtil.parse("1973-08-30"), date1));
+ }
+}
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/DateUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/DateUtilTest.java
index 984c5f246..4e2e8289a 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/date/DateUtilTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/DateUtilTest.java
@@ -834,7 +834,8 @@ public class DateUtilTest {
final String d1 = "2000-02-29";
final String d2 = "2018-02-28";
final int age = DateUtil.age(DateUtil.parse(d1), DateUtil.parse(d2));
- Assertions.assertEquals(18, age);
+ // issue#I6E6ZG,法定生日当天不算年龄,从第二天开始计算
+ Assertions.assertEquals(17, age);
}
@Test
@@ -846,6 +847,28 @@ public class DateUtilTest {
});
}
+ @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,法定生日当天不算年龄,从第二天开始计算
+ Assertions.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,法定生日当天不算年龄,从第二天开始计算
+ Assertions.assertEquals(1, age);
+ }
+
@Test
public void localDateTimeTest() {
// 测试字符串与LocalDateTime的互相转换