From 554ab6b20a16eb5a88140d4c67680277807a54ea Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 1 Nov 2019 21:04:14 +0800 Subject: [PATCH] fix leepYear bug --- CHANGELOG.md | 1 + .../java/cn/hutool/core/date/DateBetween.java | 11 ++++++ .../java/cn/hutool/core/date/DateUtil.java | 35 ++++++++++--------- .../cn/hutool/core/date/DateBetweenTest.java | 13 +++++-- .../cn/hutool/core/date/DateUtilTest.java | 8 +++++ 5 files changed, 49 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bdf987df..530e12422 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Bug修复 * 【db】 修复MetaUtil.getTableMeta()方法未释放ResultSet的bug(issue#I148GH@Gitee) +* 【core】 修复DateUtil.age闰年导致的问题(issue#I14BVN@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateBetween.java b/hutool-core/src/main/java/cn/hutool/core/date/DateBetween.java index 2a4f354a4..48327c195 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateBetween.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateBetween.java @@ -5,6 +5,7 @@ import java.util.Calendar; import java.util.Date; 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); 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)); long between = endCal.getTimeInMillis() - beginCal.getTimeInMillis(); if (between < 0) { diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java index 38a3461f1..0ba746133 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java @@ -1710,6 +1710,16 @@ public class DateUtil { return age(birthDay, date()); } + /** + * 是否闰年 + * + * @param year 年 + * @return 是否闰年 + */ + public static boolean isLeapYear(int year) { + return new GregorianCalendar().isLeapYear(year); + } + /** * 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄 * @@ -1725,17 +1735,20 @@ public class DateUtil { 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); int age = year - cal.get(Calendar.YEAR); - int monthBirth = cal.get(Calendar.MONTH); + final int monthBirth = cal.get(Calendar.MONTH); 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--; } @@ -1747,16 +1760,6 @@ public class DateUtil { return age; } - /** - * 是否闰年 - * - * @param year 年 - * @return 是否闰年 - */ - public static boolean isLeapYear(int year) { - return new GregorianCalendar().isLeapYear(year); - } - /** * 判定给定开始时间经过某段时间后是否过期 * diff --git a/hutool-core/src/test/java/cn/hutool/core/date/DateBetweenTest.java b/hutool-core/src/test/java/cn/hutool/core/date/DateBetweenTest.java index 798e815a6..23e1284be 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/DateBetweenTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/DateBetweenTest.java @@ -1,11 +1,10 @@ package cn.hutool.core.date; -import java.util.Date; - +import cn.hutool.core.date.BetweenFormater.Level; import org.junit.Assert; import org.junit.Test; -import cn.hutool.core.date.BetweenFormater.Level; +import java.util.Date; public class DateBetweenTest { @@ -28,6 +27,14 @@ public class DateBetweenTest { Assert.assertEquals(0, betweenYear2); } + @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() { Date start = DateUtil.parse("2017-02-01 12:23:46"); diff --git a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java index f826135be..d26c7f54b 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java @@ -616,4 +616,12 @@ public class DateUtilTest { DateTime date = DateUtil.date(localDateTime); 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); + } }