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是月的模;

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

 

五、补充

1,简要说明目的及基本方案

  一种基于java技术实现倒计时的方法,指定两个时间点,计算出时间间隔。比如,当前时刻2022-08-11 10:26:30,未来时刻2099-12-31 23:59:59,则倒计时时间为:77年4月20日13时33分29秒。该方法统一处理了月份有28天、29天、30天、31天的情况,以及未来时间点的秒针、分针、时针、日、月比当前时间点的秒针、分针、时针、日、月小的情况,模拟了未来时刻倒计时到当前时刻的完整过程。

2,相关术语解释

  时刻:时间点;

  时间:时间段、时间跨度;

  Calendar:java jdk自带的一个日历工具类,可以将时刻拆成年、月、周、日、时、分、秒等维度。

3,详细介绍背景知识

  生活中人们很多事情是按照计划行事的,比如6点起床、9点上班、18点下班、23点睡觉,计划中很重要的一个元素就是时刻。如果计划是需要准备的,那么当事人不仅需要知道计划的时刻,还需要知道截止到该时刻的时间跨度。

4,数学减法的借位法

  本方法完全参考数学减法的借位法,如下图:

  

5,技术方案的详细阐述

本方法模拟了未来时刻倒走到当前时刻的过程。

秒针倒走:

当前时刻

 

 

x

x

x

x

x

30

 

未来时刻

 

 

x

x

x

x

x

45

情况1,秒值大于等于

x

x

x

x

40

15

情况2,秒值小于

 

当前时刻的秒值和未来时刻的秒值存在两种关系:

情况1:未来时刻的秒值大于等于当前时刻的秒值,则倒走的秒值为未来时刻的秒值减去当前时刻的秒值;比如上图,当前时刻的秒值为30,未来时刻的秒值为45,则倒走的秒值为45减去30等于15秒;

情况2:未来时刻的秒值小于当前时刻的秒值,则未来时刻的秒值需要先向分值借1分钟(60秒),则倒走的秒值为未来时刻的秒值先加上60(秒)再减去当前时刻的秒值;比如上图,当前时刻的秒值为30,未来时刻的秒值为15,则倒走的秒值为15加上60减去30等于45秒;需要注意的是,这种情况下,分值需要减去1,比如上图分值原先为40,处理秒值后变为40减去1等于39;不用担心分值为0(借位或者连续借位)的情况,通过Calendar函数可以获取时刻减去1分钟的时刻值;

分针倒走:

当前时刻

 

 

x

x

x

x

30

x

 

未来时刻

 

 

x

x

x

x

45

x

情况1,分值大于等于

x

x

x

18

15

x

情况2,分值小于

当前时刻的分值和未来时刻的分值存在两种关系:

情况1:未来时刻的分值大于等于当前时刻的分值,则倒走的分值为未来时刻的分值减去当前时刻的分值;比如上图,当前时刻的分值为30,未来时刻的分值为45,则倒走的分值为45减去30等于15分;

情况2:未来时刻的分值小于当前时刻的分值,则未来时刻的分值需要先向时值借1小时(60分钟),则倒走的分值为未来时刻的分值先加上60(分钟)再减去当前时刻的分值;比如上图,当前时刻的分值为30,未来时刻的分值为15,则倒走的分值为15加上60减去30等于45分;需要注意的是,这种情况下,时值需要减去1,比如上图时值原先为18,处理分值后变为18减去1等于17;不用担心时值为0(借位或者连续借位)的情况,通过Calendar函数可以获取时刻减去1小时的时刻值;

时针、日、月倒走的过程则与秒针、分针相同;

年值为以上秒、分、时、日、月都处理后,未来时刻的年值减去当前时刻的年值;

完整的流程如下图:

     

 

6,构思的关键点

(1)将数学减法中的借位法应用到了计算机对时间跨度的计算中;

(2)模拟了时间行走或者倒走的过程,没有孤立时间跨度各个维度(年、月、日、时、分、秒)之间的关系;

posted @ 2022-04-20 15:50  seeAll  阅读(3200)  评论(0编辑  收藏  举报