【Java】根据日历计算2个时间相差多少#自然#年、月、日、小时、分钟、秒

iOS 自带了控件,可以自动根据日历来计算 2 个时间相差的自然年、月、日、小时、分钟、秒。Java 没有自带此方法,只能自己来算了~ 一、竖式减法实现 我

iOS 自带了控件,可以自动根据日历来计算 2 个时间相差的自然年、月、日、小时、分钟、秒。Java 没有自带此方法,只能自己来算了~

一、竖式减法实现

我自己写了一个方法,测试了一些时间和 iOS 作对比,暂时没有发现什么问题。如有错误,欢迎指正,也欢迎提意见~

源码见:TimeIntervalUtils.java

主要方法是 int[] getTimeIntervalArray(Calendar nextDate, Calendar previousDate) 。

主要思路是:

根据数学的竖式减法,从低位由 "秒→年" 依次进行减法计算,不够则向前借一位。

这里先分别将 [年, 月, 日, 小时, 分钟, 秒] 每一位的差值计算出来,然后从低位开始由 "秒→年" 依次判断:如果小于 0 ,则向前借一位,当前位补上对应的值,前一位则需要减1。

补值这里应该也好理解:"秒"、"分"补 60,"时"补 24,"月"补 12

需要注意的是 "",也就是"天数"的处理。因为是按照日历上的日期来计算的日期差值,所以需要考虑到月份的问题,每个月的天数是不一样的,那么补值也是不一样的。每个月的天数可能有28、29、30、31天,这里我是按照截止日期 nextDate 的上一个月的天数来作补值的。比如 nextDate 是 20160229,那么上个月是 1 月份,补值是 31 天。

/*** 获取 2 个时间的自然年历的时间间隔** @param nextDate     后面的时间,需要大于 previousDate* @param previousDate 前面的时间* @return [年, 月, 日, 小时, 分钟, 秒]的数组*/
public static int[] getTimeIntervalArray(Calendar nextDate, Calendar previousDate) {int year = nextDate.get(Calendar.YEAR) - previousDate.get(Calendar.YEAR);int month = nextDate.get(Calendar.MONTH) - previousDate.get(Calendar.MONTH);int day = nextDate.get(Calendar.DAY_OF_MONTH) - previousDate.get(Calendar.DAY_OF_MONTH);int hour = nextDate.get(Calendar.HOUR_OF_DAY) - previousDate.get(Calendar.HOUR_OF_DAY);// 24小时制int min = nextDate.get(Calendar.MINUTE) - previousDate.get(Calendar.MINUTE);int second = nextDate.get(Calendar.SECOND) - previousDate.get(Calendar.SECOND);boolean hasBorrowDay = false;// "时"是否向"天"借过一位if (second < 0) {second += 60;min--;}if (min < 0) {min += 60;hour--;}if (hour < 0) {hour += 24;day--;hasBorrowDay = true;}if (day < 0) {// 计算截止日期的上一个月有多少天,补上去Calendar tempDate = (Calendar) nextDate.clone();tempDate.add(Calendar.MONTH, -1);// 获取截止日期的上一个月day += tempDate.getActualMaximum(Calendar.DAY_OF_MONTH);// nextDate是月底最后一天,且day=这个月的天数,即是刚好一整个月,比如20160131~20160229,day=29,实则为1个月if (!hasBorrowDay&& nextDate.get(Calendar.DAY_OF_MONTH) == nextDate.getActualMaximum(Calendar.DAY_OF_MONTH)// 日期为月底最后一天&& day >= nextDate.getActualMaximum(Calendar.DAY_OF_MONTH)) {// day刚好是nextDate一个月的天数,或大于nextDate月的天数(比如2月可能只有28天)day = 0;// 因为这样判断是相当于刚好是整月了,那么不用向 month 借位,只需将 day 置 0} else {// 向month借一位month--;}}if (month < 0) {month += 12;year--;}return new int[]{year, month, day, hour, min, second};
}

重点讲一下 day < 0 的情况。

if (day < 0) {// 计算截止日期的上一个月有多少天,补上去Calendar tempDat