Browse Source

fix leepYear bug

Looly 6 years ago
parent
commit
554ab6b20a

+ 1 - 0
CHANGELOG.md

@@ -13,6 +13,7 @@
 
 
 ### Bug修复
 ### Bug修复
 * 【db】         修复MetaUtil.getTableMeta()方法未释放ResultSet的bug(issue#I148GH@Gitee)
 * 【db】         修复MetaUtil.getTableMeta()方法未释放ResultSet的bug(issue#I148GH@Gitee)
+* 【core】       修复DateUtil.age闰年导致的问题(issue#I14BVN@Gitee)
 
 
 -------------------------------------------------------------------------------------------------------------
 -------------------------------------------------------------------------------------------------------------
 
 

+ 11 - 0
hutool-core/src/main/java/cn/hutool/core/date/DateBetween.java

@@ -5,6 +5,7 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.Date;
 
 
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.lang.Assert;
+import cn.hutool.core.lang.Console;
 
 
 /**
 /**
  * 日期间隔
  * 日期间隔
@@ -134,6 +135,16 @@ public class DateBetween implements Serializable{
 
 
 		int result = endCal.get(Calendar.YEAR) - beginCal.get(Calendar.YEAR);
 		int result = endCal.get(Calendar.YEAR) - beginCal.get(Calendar.YEAR);
 		if (false == isReset) {
 		if (false == isReset) {
+			// 考虑闰年的2月情况
+			if(Calendar.FEBRUARY == beginCal.get(Calendar.MONTH) && Calendar.FEBRUARY == endCal.get(Calendar.MONTH)){
+				if(beginCal.get(Calendar.DAY_OF_MONTH) == beginCal.getActualMaximum(Calendar.DAY_OF_MONTH)
+				&& endCal.get(Calendar.DAY_OF_MONTH) == endCal.getActualMaximum(Calendar.DAY_OF_MONTH)){
+					// 两个日期都位于2月的最后一天,此时月数按照相等对待,此时都设置为1号
+					beginCal.set(Calendar.DAY_OF_MONTH, 1);
+					endCal.set(Calendar.DAY_OF_MONTH, 1);
+				}
+			}
+
 			endCal.set(Calendar.YEAR, beginCal.get(Calendar.YEAR));
 			endCal.set(Calendar.YEAR, beginCal.get(Calendar.YEAR));
 			long between = endCal.getTimeInMillis() - beginCal.getTimeInMillis();
 			long between = endCal.getTimeInMillis() - beginCal.getTimeInMillis();
 			if (between < 0) {
 			if (between < 0) {

+ 19 - 16
hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java

@@ -1711,6 +1711,16 @@ public class DateUtil {
 	}
 	}
 
 
 	/**
 	/**
+	 * 是否闰年
+	 *
+	 * @param year 年
+	 * @return 是否闰年
+	 */
+	public static boolean isLeapYear(int year) {
+		return new GregorianCalendar().isLeapYear(year);
+	}
+
+	/**
 	 * 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄
 	 * 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄
 	 *
 	 *
 	 * @param birthDay      生日
 	 * @param birthDay      生日
@@ -1725,17 +1735,20 @@ public class DateUtil {
 			throw new IllegalArgumentException(StrUtil.format("Birthday is after date {}!", formatDate(dateToCompare)));
 			throw new IllegalArgumentException(StrUtil.format("Birthday is after date {}!", formatDate(dateToCompare)));
 		}
 		}
 
 
-		int year = cal.get(Calendar.YEAR);
-		int month = cal.get(Calendar.MONTH);
-		int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
+		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.setTime(birthDay);
 		cal.setTime(birthDay);
 		int age = year - cal.get(Calendar.YEAR);
 		int age = year - cal.get(Calendar.YEAR);
 
 
-		int monthBirth = cal.get(Calendar.MONTH);
+		final int monthBirth = cal.get(Calendar.MONTH);
 		if (month == monthBirth) {
 		if (month == monthBirth) {
-			int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
-			if (dayOfMonth < dayOfMonthBirth) {
+
+			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) {
 				// 如果生日在当月,但是未达到生日当天的日期,年龄减一
 				// 如果生日在当月,但是未达到生日当天的日期,年龄减一
 				age--;
 				age--;
 			}
 			}
@@ -1748,16 +1761,6 @@ public class DateUtil {
 	}
 	}
 
 
 	/**
 	/**
-	 * 是否闰年
-	 *
-	 * @param year 年
-	 * @return 是否闰年
-	 */
-	public static boolean isLeapYear(int year) {
-		return new GregorianCalendar().isLeapYear(year);
-	}
-
-	/**
 	 * 判定给定开始时间经过某段时间后是否过期
 	 * 判定给定开始时间经过某段时间后是否过期
 	 *
 	 *
 	 * @param startDate   开始时间
 	 * @param startDate   开始时间

+ 10 - 3
hutool-core/src/test/java/cn/hutool/core/date/DateBetweenTest.java

@@ -1,11 +1,10 @@
 package cn.hutool.core.date;
 package cn.hutool.core.date;
 
 
-import java.util.Date;
-
+import cn.hutool.core.date.BetweenFormater.Level;
 import org.junit.Assert;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.Test;
 
 
-import cn.hutool.core.date.BetweenFormater.Level;
+import java.util.Date;
 
 
 public class DateBetweenTest {
 public class DateBetweenTest {
 
 
@@ -29,6 +28,14 @@ public class DateBetweenTest {
 	}
 	}
 
 
 	@Test
 	@Test
+	public void betweenYearTest2() {
+		Date start = DateUtil.parse("2000-02-29");
+		Date end = DateUtil.parse("2018-02-28");
+		long betweenYear = new DateBetween(start, end).betweenYear(false);
+		Assert.assertEquals(18, betweenYear);
+	}
+
+	@Test
 	public void betweenMonthTest() {
 	public void betweenMonthTest() {
 		Date start = DateUtil.parse("2017-02-01 12:23:46");
 		Date start = DateUtil.parse("2017-02-01 12:23:46");
 		Date end = DateUtil.parse("2018-02-01 12:23:46");
 		Date end = DateUtil.parse("2018-02-01 12:23:46");

+ 8 - 0
hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java

@@ -616,4 +616,12 @@ public class DateUtilTest {
 		DateTime date = DateUtil.date(localDateTime);
 		DateTime date = DateUtil.date(localDateTime);
 		Assert.assertEquals("2017-05-06 08:30:00", date.toString());
 		Assert.assertEquals("2017-05-06 08:30:00", date.toString());
 	}
 	}
+
+	@Test
+	public void ageTest(){
+		String d1 = "2000-02-29";
+		String d2 = "2018-02-28";
+		final int age = DateUtil.age(DateUtil.parseDate(d1), DateUtil.parseDate(d2));
+		Assert.assertEquals(18, age);
+	}
 }
 }