对于两个日期求相差多少年,多少月,多少天,只需取对应日期的年,月,日,两两求差,若某一项差值为负数,则向高位借一。一般情况下都是用较大的日期作为被减数,较小的日期作为减数,所以只有两个日期的月差和日差存在负值的情况。对于不需要向高位借一的年差以及月差为正和日差为正的情况比较简单,就不讨论,下面就针对月差与日差向上借一进行讨论。
一、月差为负
例如:2020-03-15 和 2018-09-11:
年差 = 2020 - 2018 = 2
月差 = 3 - 9 = -6
日差 = 15 - 11 = 4
其中:月差为负需要向上(年差)借一:
年差 = 2 -1 = 1
月差 = -6 + 12 = 6
日差 = 4
综上:2020-03-15 和 2018-09-11 间相差 1 年 6个月 4天
二、日差为负
例如:2020-03-10 和 2018-02-15
年差 = 2020 - 2018 = 2
月差 = 3 - 2 = 1
日差 = 10 - 15 = -5
其中:日差为负需要向上(月差)借一:
年差 = 2
月差 = 1 - 1 = 0
日差 = - 5 + ?
到这里有个问题,1 年是固定 12 个月的,所以月差向上借一可以加 12,但 1 个 月可能有 31天,30 天, 29 天, 28 天,其中 29 天和 28 天 分别对应的是闰年和平年的2月份,所以日差到底是补多少呢?
首先,需要一个判断平年和闰年的方法,(普通年能被4整除且不能被100整除的为闰年,世纪年能被400整除的是闰年),java 代码实现如下:
/**
* 是否是闰年
* @return
*/
public static boolean isLeapYear(int year){
if (year % 100 == 0) {
return year % 400 == 0;
} else {
return year % 4 == 0;
}
}
然后,需要一个判断向月份借的天数,java 代码实现如下:
/**
* 获取对应月份的天数
* @param year
* @param month
* @return
*/
public static int daysOfMonth(int year,int month) {
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: return 31;
case 2:if (isLeapYear(year)) {
return 29;
} else {
return 28;
}
default:return 30;
}
}
最后,判断月差向上借的天数的方法有了,那么实际上传哪个月份参数呢,答案是减数所对应的月份(这里跟数值运算不一样,至于为何不一样,可自行例证), 本实例中应该传日期 2018-02-15 对应的 2。2018 年为 平年,即最终结果如下:
年差 = 2
月差 = 1 - 1 = 0
日差 = - 5 + 28 = 23
综上:2020-03-10 和 2018-02-15 相差 2 年 0 月 23天
三、最终代码
注意:其中 toDate > fromDate
public static String getAgeStr(Date fromDate, Date toDate) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(fromDate);
int fromYear = calendar.get(Calendar.YEAR);
int fromMonth = calendar.get(Calendar.MONTH);
int fromDay = calendar.get(Calendar.DAY_OF_MONTH);
calendar.setTime(toDate);
int toYear = calendar.get(Calendar.YEAR);
int toMonth = calendar.get(Calendar.MONTH);
int toDay = calendar.get(Calendar.DAY_OF_MONTH);
int year = toYear - fromYear;
int month = toMonth - fromMonth;
int day = toDay - fromDay;
if (month < 0) {
month +=12;
year -= 1;
}
if (day < 0) {
day += daysOfMonth(fromYear,fromMonth+1);
month -= 1;
}
return year + "年" + month +"月" + day + "天";
}