計算2個時間範圍之內的有效工作時長

原始需求:

某個員工提交xxxxx申請,需要領導審批,領導收到待辦通知。

問:領導從收到審批待辦開始,到執行審批操作,用了多少分鐘?(有效工作時長)

類似問題:你開發某個功能,從xx開始,到xx做好發佈,一共用了多少有效工作時長?

 

那何爲有效工作時長?

答:就是按實際上班時間嘛,比如上午幾點上班,幾點開始午休,下午幾點上班,幾點下班?公司是否是雙休?。。。。。之類的

參數舉例:

1.每天上班時間,如:

A、不定義上班時間

B、上班時間00:00到24:00  (其實就是A)

C、上班時間09:00到17:00

D、上班時間09:00到12:00;14:00到17:00   (有午休)

E、上班時間09:00到12:00;14:00到17:00   (其實就是D)

    public static List<Map<String, String>> getOnWorkTimes() {
        List<Map<String, String>> onWorks = new ArrayList<Map<String, String>>(2);
        // 上班時間08:30-12:00,13:00-17:30
        Map<String, String> work1 = new HashMap<String, String>(2);
        Map<String, String> work2 = new HashMap<String, String>(2);
        work1.put("begin", "08:30:00");
        work1.put("end", "12:00:00");
        work2.put("begin", "13:00:00");
        work2.put("end", "17:30:00");
        onWorks.add(work1);
        onWorks.add(work2);
        return onWorks;
    }

 

2.是否排除週末,如:

A、是

B、否

 

定義一個方法,大概是長這樣:

 

看似簡單,其實情況複雜:

一、同一天

1.就是同一天(這裏也好多情況。。。。。。。自己領悟)

2.排除週末:週五到週六這種

3.排除週末:週六到下週一這種

二、跨天

三、多天

多天只需要取前後2天按上面的一、二處理,中間的每天都是完整小時

上代碼吧:(2個java文件,main方法測試效果)

A.工具類:MyUtil.java ,實現一些通用的方法,比如必要的日期格式化等:

package com.solar.oa.card.hikvision.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * @ClassName: MyUtil.java
 * @Description: TODO 
 * @date 2021年1月14日 下午9:03:31
 * @author yqwang
 */
public class MyUtil {
    public static String PATTERN_HH_MM_SS = "HH:mm:ss";
    public static String PATTERN_DEFAULT = "yyyy-MM-dd";
    public static String PATTERN_FULL = "yyyy-MM-dd HH:mm:ss";
    /**
     * 相差毫秒數
     * "10:00:00", "10:01:00", "HH:mm:ss" -->6000
     * @return end-begin
     */
    public static long diffMilliseconds(String begin, String end, String pattern) {
        Date b = string2Date(begin, pattern);
        Date e = string2Date(end, pattern);
        if(b==null || e==null){
            return 0;
        }
        return e.getTime() - b.getTime();
    }

    /**日期格式化*/
    public static Date formatDate(Date date, String... pattern) {
        try {
            if (date == null) {
                return null;
            }
            SimpleDateFormat formatter = null;
            if (pattern != null && pattern.length > 0) {
                formatter = new SimpleDateFormat(pattern[0].toString());
            } else {
                formatter = new SimpleDateFormat(PATTERN_DEFAULT);
            }
            return formatter.parse(formatter.format(date));
        } catch (Exception e) {
            return null;
        }
    }

    /**字符串轉日期*/
    public static Date string2Date(String dateStr, String... pattern) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        try {
            SimpleDateFormat formatter = null;
            if (pattern != null && pattern.length > 0) {
                formatter = new SimpleDateFormat(pattern[0].toString());
            } else {
                formatter = new SimpleDateFormat(PATTERN_DEFAULT);
            }
            return formatter.parse(dateStr);
        } catch (Exception e) {
            return null;
        }
    }

    /**日期轉字符串*/
    public static String date2String(Date date, String... pattern) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat formatter = null;
        if (pattern != null && pattern.length > 0) {
            formatter = new SimpleDateFormat(pattern[0].toString());
        } else {
            formatter = new SimpleDateFormat(PATTERN_DEFAULT);
        }
        return formatter.format(date);
    }

    /**
     * 獲取2個日期之間的日期列表
     * @param fromDate
     * @param toDate
     * @param excludeWeekend 是否排除週末
     */
    public static List<Date> getBetweenDates(String fromDateStr, String toDateStr, Boolean excludeWeekend) {
        List<Date> stamps = new ArrayList<>();
        Date fromDate = string2Date(fromDateStr);
        Date toDate = string2Date(toDateStr);
        while (fromDate.getTime() <= toDate.getTime()) {
            // 需要排除週末,則非週末的日期才添加到集合
            if (excludeWeekend) {
                if (!isWeekend(fromDate)) {
                    stamps.add(fromDate);
                }
            } else {
                stamps.add(fromDate);
            }
            fromDate = addDays(fromDate, 1);
        }
        if (stamps.size() == 0){
            return stamps;
        }
        
        int days = stamps.size();
        Date first = stamps.get(0),last = stamps.get(days-1);
        //from和days.get(0)是同一天,則集合中的第一個元素刷一下
        if(first.getTime() == string2Date(fromDateStr).getTime() ){
            stamps.set(0, string2Date(fromDateStr, PATTERN_FULL));
        }
        //to和days.get(last)是同一天,則集合中的最後一個元素刷一下
        if(last.getTime() == string2Date(toDateStr).getTime() ){
            stamps.set(days-1, string2Date(toDateStr, PATTERN_FULL));
        }
        
        return stamps;
    }

    /**
     * 某個時間加幾天
     * @param date 某個時間基礎
     * @param months 加的天份數(負數爲減)
     * @return
     */
    public static Date addDays(Date date, Integer days) {
        Calendar calendar = Calendar.getInstance(); // 得到日曆
        calendar.setTime(date);// 把當前時間賦給日曆
        calendar.add(Calendar.DATE, days); // 天加減
        return calendar.getTime(); // 加減後的時間
    }

    /**是否週末*/
    public static Boolean isWeekend(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int i = cal.get(Calendar.DAY_OF_WEEK);
        return i == 1 || i == 7;// 週日週六
    }

    /**獲取某個時間之後的有效時長*/
    public static long getAfterHHMMMills(List<Map<String, String>> onWorks, String hhmm){
        long resMills = 0;
        long tsMills = 0;
        if(CollectionUtils.isEmpty(onWorks)){
            tsMills = diffMilliseconds(hhmm,"24:00:00",PATTERN_HH_MM_SS);
            System.out.println(String.format("[%s,24:00:00]有%s分鐘",hhmm,tsMills/1000/60));
            return tsMills;
        }
        
        for (Map<String, String> work : onWorks) {
            tsMills = 0;
            // 07:20與08:30-12:00
            long millTemp = diffMilliseconds(hhmm, work.get("begin"), PATTERN_HH_MM_SS);
            long millTemp2 = diffMilliseconds(hhmm, work.get("end"), PATTERN_HH_MM_SS);
            //1提前2未到3之間
            if (millTemp > 0){
                System.out.print(String.format("%s < [%s,%s]", hhmm,work.get("begin"),work.get("end")));
                tsMills += diffMilliseconds(work.get("begin"), work.get("end"), PATTERN_HH_MM_SS);
            }else if(millTemp2 < 0){
                System.out.print(String.format("%s > [%s,%s]", hhmm,work.get("begin"),work.get("end")));
            }else{
                System.out.print(String.format("%s in [%s,%s]", hhmm,work.get("begin"),work.get("end")));
                tsMills += millTemp2;
            }
            resMills += tsMills;
            System.out.println(String.format("之後有%s分鐘", tsMills/1000/60));
        }
        return resMills;
    }
    /**獲取某個時間之前的有效時長*/
    public static long getBeforeHHMMMills(List<Map<String, String>> onWorks, String hhmm){
        long resMills = 0;
        long tsMills = 0;
        if(CollectionUtils.isEmpty(onWorks)){
            tsMills = diffMilliseconds("00:00:00", hhmm, PATTERN_HH_MM_SS);
            System.out.println(String.format("[00:00:00,%s]有%s分鐘",hhmm,tsMills/1000/60));
            return tsMills;
        }
        
        for (Map<String, String> work : onWorks) {
            tsMills = 0;
            // 07:20與08:30-12:00
            long millTemp = diffMilliseconds(hhmm, work.get("begin"), PATTERN_HH_MM_SS);
            long millTemp2 = diffMilliseconds(hhmm, work.get("end"), PATTERN_HH_MM_SS);
            //1提前2未到3之間
            if (millTemp > 0){
                System.out.print(String.format("%s < [%s,%s]", hhmm,work.get("begin"),work.get("end")));
            }else if(millTemp2 < 0){
                System.out.print(String.format("%s > [%s,%s]", hhmm,work.get("begin"),work.get("end")));
                tsMills += diffMilliseconds(work.get("begin"), work.get("end"), PATTERN_HH_MM_SS);
            }else{
                System.out.print(String.format("%s in [%s,%s]", hhmm,work.get("begin"),work.get("end")));
                tsMills += (-millTemp);
            }
            resMills += tsMills;
            System.out.println(String.format("之前有%s分鐘", tsMills/1000/60));
        }
        return resMills;
    }
    
    /**
     * 毫秒數轉換爲日時分秒,
     * @param ms
     * @return
     */
    public static String formatResult(long ms){
        Integer ss = 1000;
        Integer mi = ss * 60;
        Integer hh = mi * 60;
        Integer dd = hh * 24;

        Long day = ms / dd;
        Long hour = (ms - day * dd) / hh;
        Long minute = (ms - day * dd - hour * hh) / mi;
        Long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        Long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

        StringBuffer sb = new StringBuffer();
        if(day > 0) {
            sb.append(day+"天");
        }
        if(hour > 0) {
            sb.append(hour+"小時");
        }
        if(minute > 0) {
            sb.append(minute+"分");
        }
        if(second > 0) {
            sb.append(second+"秒");
        }
        if(milliSecond > 0) {
            sb.append(milliSecond+"毫秒");
        }
        return sb.toString();
    }
    
}

B.具體測試main測試:MyTest.ava,一共4個方法,實際計算就是第一個方法millsDiffExcluding(x,x,x,x)

MyTest.java的完整內容:

package com.solar.oa.card.hikvision.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;
/**
 * @ClassName: MyTest.java
 * @Description: TODO 
 * @date 2021年1月14日 下午9:04:44
 * @author yqwang
 */
public class MyTest extends MyUtil{//爲了方便用工具,我就extends了

    /**
     * 獲取開始時間至結束時間期間的有效工作時長(精確到毫秒)
     * 
     * @Title:minuteDiffExcluding
     * @Description: TODO
     * @date 2021年1月8日 下午9:20:32
     * @author yqwang
     * @param from
     * @param to
     * @param exWeek
     *            是否排除週末
     * @param onWorks
     *            上班時間可以定義 比如 上午 08:30 - 12:00  下午 13:00 - 17:30
     * @return
     */
    public static long millsDiffExcluding(String from, String to, Boolean exWeek, List<Map<String, String>> onWorks) {
        long resMills = 0;// 用於最終返回(毫秒數)
        // A.沒有定義上班時間 且  不排除週末===>end - begin
        if(CollectionUtils.isEmpty(onWorks) && !exWeek){ 
            resMills = diffMilliseconds(from,to, PATTERN_FULL);
            return resMills;
        }
        
        // B.起止時間所包含的日期(有效日期) (第一天和最後一天帶有時分秒)
        List<Date> dates = getBetweenDates(from, to, exWeek);
        int days = dates.size();
        if(days == 0){
            return 0;
        }
        System.out.println(String.format("一共%s天", days));
        System.out.println("範圍內有效的時間列表:");
        for (Date date : dates) {
            System.out.println(date2String(date, PATTERN_FULL));
        }
        
        Date first = dates.get(0),last = dates.get(days-1);
        //如果一共就1天,那就3種情況,1:from和to是同一天,2:first和from一樣,3:last和to一樣
        // C.1天   一天時,時間需要處理一下,first和last的值  doing..............  比如要排除 週末時,1月8號10點 到 1月10號9點  or 1月10號9點到1月11號10點。。。
        if(days == 1){
            System.out.println("同一天!");
            if(string2Date(from).getTime() == string2Date(to).getTime()){//同一天
                first = string2Date(from, PATTERN_FULL);
                last = string2Date(to, PATTERN_FULL);
                long s = getAfterHHMMMills(onWorks, date2String(first,PATTERN_HH_MM_SS));
                System.out.println("<相減>");
                long e = getAfterHHMMMills(onWorks, date2String(last,PATTERN_HH_MM_SS));
                resMills+= (s-e);
            }else if(first.getTime() == string2Date(from, PATTERN_FULL).getTime()){//如:週五到週六
                last = null;
                resMills+= getAfterHHMMMills(onWorks, date2String(first,PATTERN_HH_MM_SS));
            }else{//如:週六到下週一
                first = null;
                resMills+= getBeforeHHMMMills(onWorks, date2String(last,PATTERN_HH_MM_SS));
            }
        }else{
            //D.跨天(包含了2天及以上)
            resMills+=getAfterHHMMMills(onWorks, date2String(first,PATTERN_HH_MM_SS));
            resMills+=getBeforeHHMMMills(onWorks, date2String(last,PATTERN_HH_MM_SS));
        }
        
       
        
        // E.2天以上:(days-2)*一天的有效值
        if (days > 2) {
            // 每個整天的有效毫秒數
            long allDayMills = 0;
            if (CollectionUtils.isEmpty(onWorks)) {
                allDayMills = 24*60*60*1000;
            } else {
                for (Map<String, String> work : onWorks) {
                    allDayMills += diffMilliseconds(work.get("begin"), work.get("end"), PATTERN_HH_MM_SS);
                }
            }
            resMills += (days-2)*allDayMills;
            System.out.println(String.format("中間%s天,每天%s分,共%s分", days-2,allDayMills/1000/60,(days-2)*allDayMills/1000/60));
        }

        return resMills;
    }
   
    /** 定義上班時間 */
    public static List<Map<String, String>> getOnWorkTimes() {
        List<Map<String, String>> onWorks = new ArrayList<Map<String, String>>(2);
        // 上班時間08:30-12:00,13:00-17:30
        Map<String, String> work1 = new HashMap<String, String>(2);
        Map<String, String> work2 = new HashMap<String, String>(2);
        work1.put("begin", "08:30:00");
        work1.put("end", "12:00:00");
        work2.put("begin", "13:00:00");
        work2.put("end", "17:30:00");
        onWorks.add(work1);
        onWorks.add(work2);
        return onWorks;
    }
    
    // 有效時長計算
    @Test
    public void testEffTime(){
        getAfterHHMMMills(null, "07:30:00");
        getAfterHHMMMills(getOnWorkTimes(), "07:30:00");
        getAfterHHMMMills(getOnWorkTimes(), "09:30:00");
        getAfterHHMMMills(getOnWorkTimes(), "12:30:00");
        getAfterHHMMMills(getOnWorkTimes(), "14:30:00");
        getAfterHHMMMills(getOnWorkTimes(), "18:30:00");
        
        getBeforeHHMMMills(null, "07:30:00");
        getBeforeHHMMMills(getOnWorkTimes(), "07:30:00");
        getBeforeHHMMMills(getOnWorkTimes(), "09:30:00");
        getBeforeHHMMMills(getOnWorkTimes(), "12:30:00");
        getBeforeHHMMMills(getOnWorkTimes(), "14:30:00");
        getBeforeHHMMMills(getOnWorkTimes(), "18:30:00");
    }
    
    
    /*
     * 獲取開始時間至結束時間期間的有效工作時長(精確到分鐘)
     * 需求 1. 上下班時間可以定義 默認 上午 08:30 - 12:00 休息一小時 下午 13:00 - 17:30
     * 2. 可根據參數判斷是否排除週末
     */
    public static void main(String[] args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String from = "2021-01-15 09:02:00",to = "2021-01-18 15:22:00";
        List<Map<String, String>> onWorks = new ArrayList<>();
        Boolean exWeek=false;

        System.out.println(String.format("========================================沒有定義上班時間,不排除週末:%s,%s",from,to));
        long mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        //---------------------
        from = "2021-01-15 06:00:00";
        to = "2021-01-15 07:00:00";
        System.out.println(String.format("========================================同一天,不排除週末:%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = false;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        from = "2021-01-15 06:00:00";
        to = "2021-01-15 09:00:00";
        System.out.println(String.format("========================================同一天,不排除週末:%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = false;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        from = "2021-01-15 06:00:00";
        to = "2021-01-15 12:30:00";
        System.out.println(String.format("========================================同一天,不排除週末:%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = false;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        from = "2021-01-15 06:00:00";
        to = "2021-01-15 14:30:00";
        System.out.println(String.format("========================================同一天,不排除週末:%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = false;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        from = "2021-01-15 06:00:00";
        to = "2021-01-15 18:30:00";
        System.out.println(String.format("========================================同一天,不排除週末:%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = false;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        from = "2021-01-15 18:00:00";
        to = "2021-01-15 18:30:00";
        System.out.println(String.format("========================================同一天,不排除週末:%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = false;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));

        //---------------------
        from = "2021-01-15 09:00:00";
        to = "2021-01-16 15:00:00";
        System.out.println(String.format("========================================週五到週六,排除週末%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = true;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
  
        from = "2021-01-16 09:00:00";
        to = "2021-01-18 15:00:00";
        System.out.println(String.format("========================================週六到下週一,排除週末%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = true;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        from = "2021-01-16 09:00:00";
        to = "2021-01-19 15:00:00";
        System.out.println(String.format("========================================週六到下週二,排除週末%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = true;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        from = "2021-01-14 09:00:00";
        to = "2021-01-15 15:00:00";
        System.out.println(String.format("========================================2天,排除週末%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = true;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));


        from = "2021-01-15 09:00:00";
        to = "2021-01-22 15:00:00"; 
        System.out.println(String.format("========================================週五到下週五,排除週末%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = true;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        
        from = "2020-01-15 09:00:00";
        to = "2021-01-22 15:00:00"; 
        System.out.println(String.format("========================================跨年,排除週末%s,%s",from,to));
        onWorks = getOnWorkTimes();
        exWeek = true;
        mills = millsDiffExcluding(from, to, exWeek, onWorks);
        System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
        System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        
        /*// 一萬次跨年計算  (這裏如果要測試,那就請把工具類和當前文件的System.out.print給註釋掉,否則由於需要輸出,會非常影響測試!!)
        for(int i = 0;i<10000;i++){
            from = "2020-01-15 09:00:00";
            to = "2021-01-22 15:00:00"; 
            System.out.println(String.format("========================================跨年,排除週末%s,%s",from,to));
            onWorks = getOnWorkTimes();
            exWeek = true;
            mills = millsDiffExcluding(from, to, exWeek, onWorks);
            System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
            System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        }*/
        
        stopWatch.stop();
        System.out.println(String.format("計算耗時:%s", stopWatch.getTotalTimeMillis()));
    }
}

允許MyTest.java的main()方法,效果如下:

========================================沒有定義上班時間,不排除週末:2021-01-15 09:02:00,2021-01-18 15:22:00
有效工作時長:3天6小時20分
有效工作時長:4700分鐘
========================================同一天,不排除週末:2021-01-15 06:00:00,2021-01-15 07:00:00
一共1天
範圍內有效的時間列表:
2021-01-15 07:00:00
同一天!
06:00:00 < [08:30:00,12:00:00]之後有210分鐘
06:00:00 < [13:00:00,17:30:00]之後有270分鐘
<相減>
07:00:00 < [08:30:00,12:00:00]之後有210分鐘
07:00:00 < [13:00:00,17:30:00]之後有270分鐘
有效工作時長:
有效工作時長:0分鐘
========================================同一天,不排除週末:2021-01-15 06:00:00,2021-01-15 09:00:00
一共1天
範圍內有效的時間列表:
2021-01-15 09:00:00
同一天!
06:00:00 < [08:30:00,12:00:00]之後有210分鐘
06:00:00 < [13:00:00,17:30:00]之後有270分鐘
<相減>
09:00:00 in [08:30:00,12:00:00]之後有180分鐘
09:00:00 < [13:00:00,17:30:00]之後有270分鐘
有效工作時長:30分
有效工作時長:30分鐘
========================================同一天,不排除週末:2021-01-15 06:00:00,2021-01-15 12:30:00
一共1天
範圍內有效的時間列表:
2021-01-15 12:30:00
同一天!
06:00:00 < [08:30:00,12:00:00]之後有210分鐘
06:00:00 < [13:00:00,17:30:00]之後有270分鐘
<相減>
12:30:00 > [08:30:00,12:00:00]之後有0分鐘
12:30:00 < [13:00:00,17:30:00]之後有270分鐘
有效工作時長:3小時30分
有效工作時長:210分鐘
========================================同一天,不排除週末:2021-01-15 06:00:00,2021-01-15 14:30:00
一共1天
範圍內有效的時間列表:
2021-01-15 14:30:00
同一天!
06:00:00 < [08:30:00,12:00:00]之後有210分鐘
06:00:00 < [13:00:00,17:30:00]之後有270分鐘
<相減>
14:30:00 > [08:30:00,12:00:00]之後有0分鐘
14:30:00 in [13:00:00,17:30:00]之後有180分鐘
有效工作時長:5小時
有效工作時長:300分鐘
========================================同一天,不排除週末:2021-01-15 06:00:00,2021-01-15 18:30:00
一共1天
範圍內有效的時間列表:
2021-01-15 18:30:00
同一天!
06:00:00 < [08:30:00,12:00:00]之後有210分鐘
06:00:00 < [13:00:00,17:30:00]之後有270分鐘
<相減>
18:30:00 > [08:30:00,12:00:00]之後有0分鐘
18:30:00 > [13:00:00,17:30:00]之後有0分鐘
有效工作時長:8小時
有效工作時長:480分鐘
========================================同一天,不排除週末:2021-01-15 18:00:00,2021-01-15 18:30:00
一共1天
範圍內有效的時間列表:
2021-01-15 18:30:00
同一天!
18:00:00 > [08:30:00,12:00:00]之後有0分鐘
18:00:00 > [13:00:00,17:30:00]之後有0分鐘
<相減>
18:30:00 > [08:30:00,12:00:00]之後有0分鐘
18:30:00 > [13:00:00,17:30:00]之後有0分鐘
有效工作時長:
有效工作時長:0分鐘
========================================週五到週六,排除週末2021-01-15 09:00:00,2021-01-16 15:00:00
一共1天
範圍內有效的時間列表:
2021-01-15 09:00:00
同一天!
09:00:00 in [08:30:00,12:00:00]之後有180分鐘
09:00:00 < [13:00:00,17:30:00]之後有270分鐘
有效工作時長:7小時30分
有效工作時長:450分鐘
========================================週六到下週一,排除週末2021-01-16 09:00:00,2021-01-18 15:00:00
一共1天
範圍內有效的時間列表:
2021-01-18 15:00:00
同一天!
15:00:00 > [08:30:00,12:00:00]之前有210分鐘
15:00:00 in [13:00:00,17:30:00]之前有120分鐘
有效工作時長:5小時30分
有效工作時長:330分鐘
========================================週六到下週二,排除週末2021-01-16 09:00:00,2021-01-19 15:00:00
一共2天
範圍內有效的時間列表:
2021-01-18 00:00:00
2021-01-19 15:00:00
00:00:00 < [08:30:00,12:00:00]之後有210分鐘
00:00:00 < [13:00:00,17:30:00]之後有270分鐘
15:00:00 > [08:30:00,12:00:00]之前有210分鐘
15:00:00 in [13:00:00,17:30:00]之前有120分鐘
有效工作時長:13小時30分
有效工作時長:810分鐘
========================================2天,排除週末2021-01-14 09:00:00,2021-01-15 15:00:00
一共2天
範圍內有效的時間列表:
2021-01-14 09:00:00
2021-01-15 15:00:00
09:00:00 in [08:30:00,12:00:00]之後有180分鐘
09:00:00 < [13:00:00,17:30:00]之後有270分鐘
15:00:00 > [08:30:00,12:00:00]之前有210分鐘
15:00:00 in [13:00:00,17:30:00]之前有120分鐘
有效工作時長:13小時
有效工作時長:780分鐘
========================================週五到下週五,排除週末2021-01-15 09:00:00,2021-01-22 15:00:00
一共6天
範圍內有效的時間列表:
2021-01-15 09:00:00
2021-01-18 00:00:00
2021-01-19 00:00:00
2021-01-20 00:00:00
2021-01-21 00:00:00
2021-01-22 15:00:00
09:00:00 in [08:30:00,12:00:00]之後有180分鐘
09:00:00 < [13:00:00,17:30:00]之後有270分鐘
15:00:00 > [08:30:00,12:00:00]之前有210分鐘
15:00:00 in [13:00:00,17:30:00]之前有120分鐘
中間4天,每天480分,共1920分
有效工作時長:1天21小時
有效工作時長:2700分鐘
======》》》計算耗時:77ms

我已經把我能想到的情況,都測試輸出了.........................

        // 一萬次跨年計算  (這裏如果要測試,那就請把工具類和當前文件的System.out.print給註釋掉,否則由於需要輸出,會非常影響測試!!)
        for(int i = 0;i<10000;i++){
            from = "2020-01-15 09:00:00";
            to = "2021-01-22 15:00:00"; 
            System.out.println(String.format("========================================跨年,排除週末%s,%s",from,to));
            onWorks = getOnWorkTimes();
            exWeek = true;
            mills = millsDiffExcluding(from, to, exWeek, onWorks);
            System.out.println(String.format("有效工作時長:%s", formatResult(mills)));
            System.out.println(String.format("有效工作時長:%s分鐘", mills/1000/60));
        }

儘管計算10000次跨年的數據,也只需要2到3秒。

 

若各位看到問題,還請不吝賜教。當然如果能解決大家的問題,就最好了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章