java日期工具類--獲取兩個日期之間的工作日天數(只去除周六日,未去除節假日)


獲取兩個日期之間的工作日天數 (只去除周六日,未去除節假日)

其他參考資料:

兩個日期之間的工作日計算工具類
https://www.cnblogs.com/zzlp/p/5166605.html
https://blog.csdn.net/weixin_30731305/article/details/99756422

 

方法1、使用循環的方式遍歷兩個日期的每一天,當日期不屬於周六日時, 工作日 + 1
 
方法2、
1、如果兩個時間在同一周,且都不是周末日期,直接返回  時間差,提高執行效率
2、不是同一周時,將開始日期和結束日期都設置到下個周一,計算這兩個周一之間的工作日天數。
  計算開始日期到下周一,結束日期到下周一的偏移天數。 獲取到兩個偏移天數的差值。
 
總的工作日天數 = 將獲取到的工作日天數 + 偏移天數差值
 
日期工具類
DateUtils.java
 
public class DateUtils {


    /**
     * 獲取兩個時間之內的工作日時間(只去掉兩個日期之間的周末時間,法定節假日未去掉) 時間精確到日
     *
     * @param startDate
     *            -起始時間
     * @param endDate
     *            -結束時間
     * @return Long型時間差對象
     */
    public static int getWorkdayTimeInDate(Date startDate, Date endDate) {
        long start = startDate.getTime();
        long end = endDate.getTime();
        // 如果起始時間大於結束時間,將二者交換
        if (start > end) {
            long temp = start;
            start = end;
            end = temp;
        }
        // 根據參數獲取起始時間與結束時間的日歷類型對象
        Calendar sdate = Calendar.getInstance();
        Calendar edate = Calendar.getInstance();
        sdate.setTimeInMillis(start);
        edate.setTimeInMillis(end);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


        try {
            sdate.setTime(sdf.parse(sdf.format(sdate.getTime())));
            edate.setTime(sdf.parse(sdf.format(edate.getTime())));
        } catch (ParseException e) {
            e.printStackTrace();
        }


        // 如果兩個時間在同一周並且都不是周末日期,則直接返回時間差,增加執行效率
        if (sdate.get(Calendar.YEAR) == edate.get(Calendar.YEAR)
            && sdate.get(Calendar.WEEK_OF_YEAR) == edate.get(Calendar.WEEK_OF_YEAR)
            && sdate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
            && sdate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY
            && edate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
            && edate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
            long between_days = (end - start) / (1000 * 3600 * 24);
            return Integer.parseInt(String.valueOf(between_days));
        }


        // 防止開始日期在周五,結束日期在周日情況下,計算間隔天數不准確問題,開始或結束日期為周六日時,
        // 開始日期周六日,設置為下周一。
        if (sdate.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            sdate.add(Calendar.DAY_OF_MONTH, 1);
        }
        if (sdate.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            // 開始日期在周六日時,設置日期為周一
            sdate.add(Calendar.DAY_OF_MONTH, 2);
        }
        start = sdate.getTimeInMillis();
        // 結束日期為周六日時,設置為周五
        if (edate.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            edate.add(Calendar.DAY_OF_MONTH, -2);
        }
        if (edate.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            edate.add(Calendar.DAY_OF_MONTH, -1);
        }
        end = edate.getTimeInMillis();


        // 首先取得起始日期與結束日期的下個周一的日期
        Calendar snextM = getNextMonday(sdate);
        Calendar enextM = getNextMonday(edate);
        // 獲取這兩個周一之間的實際天數
        int days = 0;
        try {
            days = daysBetween(snextM.getTime(), enextM.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 獲取這兩個周一之間的工作日數(兩個周一之間的天數肯定能被7整除,並且工作日數量占其中的5/7)
        int workdays = days / 7 * 5;
        // 獲取開始時間的偏移量
        long scharge = 0;
        sdate.setTimeInMillis(start);
        edate.setTimeInMillis(end);
        if (sdate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
            && sdate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
            // 只有在開始時間為非周末的時候才計算偏移量
            scharge += (7 - sdate.get(Calendar.DAY_OF_WEEK)) * 24 * 3600000;
            scharge -= sdate.get(Calendar.HOUR_OF_DAY) * 3600000;
            scharge -= sdate.get(Calendar.MINUTE) * 60000;
            scharge -= sdate.get(Calendar.SECOND) * 1000;
            scharge -= sdate.get(Calendar.MILLISECOND);
        }
        // 獲取結束時間的偏移量
        long echarge = 0;
        if (edate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
            && edate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
            // 只有在結束時間為非周末的時候才計算偏移量
            echarge += (7 - edate.get(Calendar.DAY_OF_WEEK)) * 24 * 3600000;
            echarge -= edate.get(Calendar.HOUR_OF_DAY) * 3600000;
            echarge -= edate.get(Calendar.MINUTE) * 60000;
            echarge -= edate.get(Calendar.SECOND) * 1000;
            echarge -= edate.get(Calendar.MILLISECOND);
        }
        // 計算最終結果,具體為:workdays加上開始時間的時間偏移量,減去結束時間的時間偏移量
        long between_days = workdays + (scharge - echarge) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }


    /**
     * 獲取下周一
     *
     * @param calendar
     *            指定日期
     * @return
     */
    private static Calendar getNextMonday(Calendar calendar) {
        int addnum = 9 - calendar.get(Calendar.DAY_OF_WEEK);
        if (addnum == 8) {
            addnum = 1;// 周日的情況
        }
        calendar.add(Calendar.DATE, addnum);
        return calendar;
    }


    /**
     *
     * 計算兩個日期之間相差的天數
     *
     * @param smdate
     *            較小的時間
     *
     * @param bdate
     *            較大的時間
     *
     * @return 相差天數
     *
     * @throws ParseException
     *
     */
    public static int daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);


        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();


        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM