java获取相隔时间,年月日时分秒


一、前言

获取两个时间一前一后之间的跨度,相隔几年几月几日几时几分几秒,例如下:

2022-04-20 13:58:30 2022-04-20 14:00:05  135

2022-02-20 12:58:30 2022-03-05 14:00:05  131135

2021-02-20 12:58:30 2022-03-05 14:00:05  10131135

二、实现

1,秒

情况1startTime的秒数 < endTime的秒数,则相隔的秒数为:endTime的秒数 - startTime的秒数,如:

2022-03-05 14:00:05 2022-04-20 13:58:30 --> 30-05=25

情况2startTime的秒数 >= 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秒,记130秒;

分针还没走到无限接近60分钟的时候,时针不会动,记比如59分;分针刚走到60分钟的时候,时钟向前走一步,分针则归零,记1小时;分针再走30分钟,记1小时30分钟;

时针还没走到无限接近24小时的时候,天不会动,记比如23小时;时针刚走到24小时的时候,天向前走一步,时针则归零,记1天;时针再走5小时,记15小时;

天还没走到无限接近当前月的天数(比如131天,闰年229天,非闰年228天)的时候,月不会动,记比如30天;天刚走到31天的时候,月向前走一步,天则归零,记1月;天再走5天,记1个月零5天;

月还没走到无限接近12个月的时候,年不会动,记比如11月;月刚走到12个月的时候,年向前走一步,月则归零,记1年;月再走5个月,记1年零5个月;

60是秒的模;

60是分钟的模;

24是小时的模;

当前月的天数是天的模;

12是月的模;

年没有模,无穷无尽了,年年岁岁花相似,岁岁年年人不同。