java获取相隔时间,年月日时分秒
一、前言
获取两个时间一前一后之间的跨度,相隔几年几月几日几时几分几秒,例如下:
2022-04-20 13:58:30 至 2022-04-20 14:00:05 :1分35秒
2022-02-20 12:58:30 至 2022-03-05 14:00:05 :13日1时1分35秒
2021-02-20 12:58:30 至 2022-03-05 14:00:05 :1年0月13日1时1分35秒
二、实现
1,秒
情况1,startTime的秒数 < endTime的秒数,则相隔的秒数为:endTime的秒数 - startTime的秒数,如:
2022-03-05 14:00:05 至 2022-04-20 13:58:30 --> 30-05=25;
情况2,startTime的秒数 >= endTime的秒数,则相隔的秒数为:endTime的秒数 + (借分钟)60秒 - startTime的秒数,如:
2022-03-05 14:00:30 至 2022-04-20 13:58:05 -->
2022-03-05 14:00:30 至 2022-04-20 13:57:65 -->
回到情况1 --> 65-30=35;
java代码使用Calendar很方便,可以获取时间的秒数,如:
2022-03-05 14:00:30的秒数是30,
2022-04-20 13:58:05的秒数是5;
也可以很方便的获得时间少了一分钟的时间,如:
2022-04-20 13:58:05少了一分钟是2022-04-20 13:57:05,
2022-04-20 13:00:05少了一分钟是2022-04-20 12:59:05,更极端的
2022-01-01 00:00:05少了一分钟是2021-12-31 23:59:05,如下图:
2,分、时、日、月
分、时、日、月和秒的计算方式相同道理。
相隔多少分钟,如:
2022-04-20 13:57:xx 至 2022-04-20 15:50:xx -->
2022-04-20 13:57:xx 至 2022-04-20 14:110:xx -->
相隔 50 + 借(1个小时=60分钟)- 57 = 53 分钟;
时、日、月同理,如下图:
三、代码
import java.util.Calendar; import java.util.Date; public static String formatDuration(Date startTime, Date endTime) { if (null == startTime || null == endTime || startTime.after(endTime)) { return null; } Calendar startCalendar = Calendar.getInstance(); startCalendar.setTime(startTime); Calendar endCalendar = Calendar.getInstance(); endCalendar.setTime(endTime); int secondDiff = endCalendar.get(Calendar.SECOND) - startCalendar.get(Calendar.SECOND); if (secondDiff < 0) { endCalendar.add(Calendar.MINUTE, -1); secondDiff = secondDiff + 60; } int minuteDiff = endCalendar.get(Calendar.MINUTE) - startCalendar.get(Calendar.MINUTE); if (minuteDiff < 0) { endCalendar.add(Calendar.HOUR_OF_DAY, -1); minuteDiff = minuteDiff + 60; } int hourDiff = endCalendar.get(Calendar.HOUR_OF_DAY) - startCalendar.get(Calendar.HOUR_OF_DAY); if (hourDiff < 0) { endCalendar.add(Calendar.DAY_OF_MONTH, -1); hourDiff = hourDiff + 24; } int dayDiff = endCalendar.get(Calendar.DAY_OF_MONTH) - startCalendar.get(Calendar.DAY_OF_MONTH); if (dayDiff < 0) { endCalendar.add(Calendar.MONTH, -1); dayDiff = dayDiff + endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); } int monthDiff = endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH); if (monthDiff < 0) { endCalendar.add(Calendar.YEAR, -1); monthDiff = monthDiff + 12; } int yearDiff = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR); int[] values = new int[]{yearDiff, monthDiff, dayDiff, hourDiff, minuteDiff, secondDiff}; String[] labels = new String[]{"年", "月", "日", "时", "分", "秒"}; // 标识是否停止检测0 boolean isStopCheckZero = false; StringBuilder builder = new StringBuilder(); for (int i = 0; i < values.length; i++) { if (!isStopCheckZero && 0 == values[i]) { continue; } isStopCheckZero = true; builder.append(values[i]).append(labels[i]); } return builder.toString(); }
四、总结
获取两个时间一前一后之间的跨度,相隔几年几月几日几时几分几秒,和进位制差不多,和闹钟差不多;
秒针还没走到无限接近正上方刻度的时候,分针不会动;
秒针刚走到正上方刻度的时候,分钟向前走一步,秒针则归零。
两个时间的跨度,就像两个闹钟分别对应两个时间,落后的闹钟开始走,另外的闹钟不动,一直走到另一个闹钟的那个时刻,这之间走了多少年多少月多少日多少时多少分多少秒。过程如下:
将落后的闹钟的秒针拨回到正上方刻度,拨了多少秒,则另外一个闹钟也拨回多少秒,另外一个闹钟得有倒着走的机制才行(闹钟能正着走,我想稍微改造一下,倒着走应该也不难);
然后让落后的闹钟开始正着走:
秒针还没走到无限接近正上方刻度的时候,分针不会动,记比如59秒;秒针刚走到60秒的时候,分钟向前走一步,秒针则归零,记1分钟;秒针再走30秒,记1分30秒;
分针还没走到无限接近60分钟的时候,时针不会动,记比如59分;分针刚走到60分钟的时候,时钟向前走一步,分针则归零,记1小时;分针再走30分钟,记1小时30分钟;
时针还没走到无限接近24小时的时候,天不会动,记比如23小时;时针刚走到24小时的时候,天向前走一步,时针则归零,记1天;时针再走5小时,记1天5小时;
天还没走到无限接近当前月的天数(比如1月31天,闰年2月29天,非闰年2月28天)的时候,月不会动,记比如30天;天刚走到31天的时候,月向前走一步,天则归零,记1月;天再走5天,记1个月零5天;
月还没走到无限接近12个月的时候,年不会动,记比如11月;月刚走到12个月的时候,年向前走一步,月则归零,记1年;月再走5个月,记1年零5个月;
60是秒的模;
60是分钟的模;
24是小时的模;
当前月的天数是天的模;
12是月的模;
年没有模,无穷无尽了,年年岁岁花相似,岁岁年年人不同。