程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 計算兩個日期之間的工作日(去掉周末和節假日),工作日節假日

計算兩個日期之間的工作日(去掉周末和節假日),工作日節假日

編輯:JAVA綜合教程

計算兩個日期之間的工作日(去掉周末和節假日),工作日節假日


公司要寫售後的一個功能,用到這個功能,在一個貼吧上找到的,整理一下,

package com.utouu.uphone.commons;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.springframework.stereotype.Component;
/**
 * 獲取工作日
 * <br>創建日期:2016年7月21日
 * <br><b>Copyright 2016 UTOUU All Rights Reserved</b>
 * @author zhushuangshuang
 * @since 1.0
 * @version 1.0
 */
@Component
public class GetWorkDay {
    /**
    * 獲取兩個時間之內的工作日時間(只去掉兩個日期之間的周末時間,法定節假日未去掉)
    *
    * @param start
    * -起始時間,共有3個重載方法,可以傳入long型,Long型,與Date型
    * @param end
    * -結束時間,共有3個重載方法,可以傳入long型,Long型,與Date型
    * @return Long型時間差對象
    */
    /*public static void main(String[] args) {
        GetWorkDay g=new GetWorkDay();
        List<Date> initHoliday;
        try {
            initHoliday = g.initHoliday();
            double days = g.getWorkdayTimeInMillisExcWeekendHolidays("2016-06-30 17-12-53","2016-08-30 11-27-50","yyyy-MM-dd HH-mm-ss",initHoliday);
            double formateToDay = g.formateToDay(days);
            String formatDuring = g.formatDuring(days);
             System.out.println(formateToDay);
            System.out.println(formatDuring);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } */
    
    private double getWorkdayTimeInMillis(long start, long end,
        List<Date> listHolidays) {
    
        // 如果起始時間大於結束時間,將二者交換
        if (start > end) {
            long temp = start;
            start = end;
            end = temp;
        }
        // 根據參數獲取起始時間與結束時間的日歷類型對象
        Calendar sdate = Calendar.getInstance();
        Calendar edate = Calendar.getInstance();
    
        sdate.setTimeInMillis(start);
        edate.setTimeInMillis(end);
    
        // 計算指定時間段內法定節假日天數的毫秒數
        long holidays = 0;
        if (listHolidays != null) {
            holidays = getHolidaysInMillis(start, end, listHolidays);
            listHolidays.clear();
        }
    
        // 如果兩個時間在同一周並且都不是周末日期,則直接返回時間差,增加執行效率
        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) != 1 && sdate
        .get(Calendar.DAY_OF_WEEK) != 7)
        && (edate.get(Calendar.DAY_OF_WEEK) != 1 && edate
        .get(Calendar.DAY_OF_WEEK) != 7)) {
        return new Long(end - start - holidays);
        }
        // 如果兩個時間在同一周並且都是周末日期,則直接返回0
        if ((sdate.get(Calendar.YEAR) == edate.get(Calendar.YEAR))
        && (sdate.get(Calendar.WEEK_OF_YEAR) == edate
        .get(Calendar.WEEK_OF_YEAR)-1)
        && (sdate.get(Calendar.DAY_OF_WEEK) == 1
        || sdate.get(Calendar.DAY_OF_WEEK) == 7)
        &&
        (edate.get(Calendar.DAY_OF_WEEK) == 1
        || edate.get(Calendar.DAY_OF_WEEK) == 7)) {
        start=validateStartTime(sdate);
        end=validateEndTime(edate);
        long result=end - start - holidays;
        return new Long(result>0?result:0);
        }
    
        start=validateStartTime(sdate);
        end=validateEndTime(edate);
    
        // 首先取得起始日期與結束日期的下個周一的日期
        Calendar snextM = getNextMonday(sdate);
        Calendar enextM = getNextMonday(edate);
    
        // 獲取這兩個周一之間的實際天數
        int days = getDaysBetween(snextM, enextM);
    
        // 獲取這兩個周一之間的工作日數(兩個周一之間的天數肯定能被7整除,並且工作日數量占其中的5/7)
        int workdays = days / 7 * 5;
    
        // 計算最終結果,具體為:workdays加上開始時間的時間偏移量,減去結束時間的時間偏移量
        double a=(double)workdays*24*3600000;
        double result = (a + calcWorkdayTimeInMillis(sdate, edate, start, end) - holidays);
       return result > 0 ? result : 0;
    }
    /***
    * 驗證開始日期是否合法,如果不合法,並返回修復後的正確日期毫秒數
    * @param sdate
    * @return
    */
    private long validateStartTime(Calendar sdate){
        if(sdate.get(Calendar.DAY_OF_WEEK) == 1)//開始日期從周日開始,如果開始時間為周末,自動修復為下周的9:00開始
        {
            sdate.add(Calendar.DATE,1);
            sdate.setTimeInMillis(sdate.getTime().getTime()- //從9點開始
            (((sdate.get(Calendar.HOUR_OF_DAY)-9) * 3600000)+ (sdate.get(Calendar.MINUTE) * 60000)+ (sdate.get(Calendar.SECOND) * 1000)));
        }else if(sdate.get(Calendar.DAY_OF_WEEK) == 7){//開始日期從周六開始
                sdate.add(Calendar.DATE,2);
                sdate.setTimeInMillis(
                sdate.getTime().getTime()- //從9點開始,如果開始時間為周末,自動修復為下周的9:00開始
                (((sdate.get(Calendar.HOUR_OF_DAY)-9) * 3600000)
               + (sdate.get(Calendar.MINUTE) * 60000)
               + (sdate.get(Calendar.SECOND) * 1000)));
        }
            return sdate.getTimeInMillis();
    }


    /***
    * 驗證結束日期是否合法,如果不合法,並返回修復後的正確日期毫秒數
    * @param sdate
    * @return
    */
    private long validateEndTime(Calendar edate)
    {
        if(edate.get(Calendar.DAY_OF_WEEK) == 1)//結束日期是周日,如果結束日期是周六、周末自動修復為這周五18:00
        {
        edate.add(Calendar.DATE,-2);
        edate.setTimeInMillis(
        edate.getTime().getTime()+
        (18*3600000-((edate.get(Calendar.HOUR_OF_DAY) * 3600000)
        + (edate.get(Calendar.MINUTE) * 60000)
        + (edate.get(Calendar.SECOND) * 1000))));
        }else if(edate.get(Calendar.DAY_OF_WEEK) == 7){//結束日期是周六,如果結束日期是周六、周末自動修復為這周五18:00
            edate.add(Calendar.DATE,-1);
            edate.setTimeInMillis(
            edate.getTime().getTime()+
        (18*3600000-((edate.get(Calendar.HOUR_OF_DAY) * 3600000)
        + (edate.get(Calendar.MINUTE) * 60000)
        + (edate.get(Calendar.SECOND) * 1000))));}
        return edate.getTimeInMillis();
    }
    /***
    * 計算兩個日期間的工作日天數,除周六日
    *
    * @param sdate
    * @param edate
    * @return
    */
    private long calcWorkdayTimeInMillis(Calendar sdate, Calendar edate,long start, long end) {
        // 獲取開始時間的偏移量
        long scharge = 0;
        if (sdate.get(Calendar.DAY_OF_WEEK) != 1
        && sdate.get(Calendar.DAY_OF_WEEK) != 7) {
        // 只有在開始時間為非周末的時候才計算偏移量
        scharge += (sdate.get(Calendar.HOUR_OF_DAY) * 3600000);
        scharge += (sdate.get(Calendar.MINUTE) * 60000);
        scharge += (sdate.get(Calendar.SECOND) * 1000);
        scharge = ((24 * 3600000) - scharge);
    
        scharge += ((sdate.getTime().getTime() - start) - (3 * 24 * 3600000));
        }
        // (24*3600000=86400000)-((9*3600000+1800000)=34200000)+(3*24*3600000=259200000)-(2*24*3600000)=
        // 86400000-34200000=52200000
        // 獲取結束時間的偏移量
        long echarge = 0;
        if (edate.get(Calendar.DAY_OF_WEEK) != 1
        && edate.get(Calendar.DAY_OF_WEEK) != (7)) {
        // 只有在結束時間為非周末的時候才計算偏移量
        echarge += (edate.get(Calendar.HOUR_OF_DAY) * 3600000);
        echarge += (edate.get(Calendar.MINUTE) * 60000);
        echarge += (edate.get(Calendar.SECOND) * 1000);
        echarge = ((24 * 3600000) - echarge);
        echarge += (edate.getTime().getTime() - end) - (24 * 3600000);
        echarge -= (2 * 24 * 3600000);
        }
        // (24*3600000=86400000)-(18*3600000=64800000)+(24*3=259200000)
        if (scharge < 0 || echarge < 0)
        scharge = echarge = 0;
        return scharge - echarge;
    }
    
    /**
    * 獲取兩個時間之內的工作日時間(只去掉兩個日期之間的周末時間,法定節假日未去掉)
    *
    * @param start
    * -起始時間,共有3個重載方法,可以傳入long型,Long型,與Date型
    * @param end
    * -結束時間,共有3個重載方法,可以傳入long型,Long型,與Date型
    * @return Long型時間差對象
    */
    public double getWorkdayTimeInMillisExcWeekend(long start, long end) {
        return getWorkdayTimeInMillis(start, end);
    }

    /***
    * 獲取兩個時間之內的工作日時間(去掉兩個日期之間的周末時間,法定節假日時間)
    *
    * @param start
    * @param end
    * @return
    */
    public double getWorkdayTimeInMillisExcWeekendHolidays(String start,String end, String format, List<Date> listHolidays) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date sdate;
        Date edate;
        try {
            sdate = sdf.parse(start);
            edate = sdf.parse(end);
            return getWorkdayTimeInMillis(sdate.getTime(), edate.getTime(),
            listHolidays);
            } catch (ParseException e) {
            e.printStackTrace();
            return new Long(0);
        }
    }
    
    public double getWorkdayTimeInMillis(Long start, Long end) {
        return getWorkdayTimeInMillis(start.longValue(), end.longValue(), null);
        }

        public double getWorkdayTimeInMillis(Date start, Date end) {
        return getWorkdayTimeInMillis(start.getTime(), end.getTime(), null);
        }

        public double getWorkdayTimeInMillis(String start, String end, String format) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Date sdate;
            Date edate;
            try {
                sdate = sdf.parse(start);
                edate = sdf.parse(end);
                return getWorkdayTimeInMillis(sdate, edate);
            } catch (ParseException e) {
                e.printStackTrace();
                return new Long(0);
            }
            }
    
            private long getHolidaysInMillis(long start, long end,
                List<Date> listHolidays) {
                Calendar scalendar = Calendar.getInstance();
                Calendar ecalendar = Calendar.getInstance();
                int daysofH = 0;
                try {
        
                scalendar.setTimeInMillis(start);
                ecalendar.setTimeInMillis(end);
        
                if (listHolidays == null)
                return new Long(0);
                Iterator<Date> iterator = listHolidays.iterator();
                while (iterator.hasNext()) {
                Calendar ca = Calendar.getInstance();
                Date hdate = iterator.next();
                ca.setTime(hdate);
                if (ca.after(scalendar) && ca.before(ecalendar)) {
                    daysofH = daysofH + 1;
                } else if (ca.getTimeInMillis() == scalendar.getTimeInMillis()) {
                    daysofH = daysofH + 1;
                } else if (ca.getTimeInMillis() == ecalendar.getTimeInMillis()) {
                    daysofH = daysofH + 1;
                }
                }
        
                } catch (Exception e) {
                    e.printStackTrace();
                    return new Long(0);
                }
                   return daysofH * 24 * 3600000;
         }
        
        
        private Calendar getNextMonday(Calendar cal) {
                int addnum = 9 - cal.get(Calendar.DAY_OF_WEEK);
                if (addnum == 8)
                addnum = 1;// 周日的情況
                cal.add(Calendar.DATE, addnum);
                return cal;
        }

            /**
            *
            * @param mss 
            * @param 要轉換的毫秒數
            * @return 該毫秒數轉換為 * days * hours * minutes * seconds 後的格式
            */
        public String formatDuring(double mss) {
            long days = (long) (mss / (1000 * 60 * 60 * 24));
            long hours = (long) ((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            long minutes = (long) ((mss % (1000 * 60 * 60)) / (1000 * 60));
            long seconds = (long) ((mss % (1000 * 60)) / 1000);
            return days + " days " + hours + " hours " + minutes + " minutes "
            + seconds + " seconds ";
            }
            
            /**
            * 獲取兩個日期之間的實際天數,支持跨年
            * @param start 
            * @param end 
            *  
            */
        /**
         * 獲得兩個日期之間的工作日
         * @since 1.0 
         * @param mss
         * @return
         * <br><b>作者: @author zhushunagshuang</b>
         * <br>創建時間:2016年7月21日 下午3:12:23
         */
        public double formateToDay(double mss){
            double days = mss / (1000 * 60 * 60 * 24);
            return days;
        }
        
        public int getDaysBetween(Calendar start, Calendar end) {
            if (start.after(end)) {
            Calendar swap = start;
            start = end;
            end = swap;
            }

            int days = end.get(Calendar.DAY_OF_YEAR)- start.get(Calendar.DAY_OF_YEAR);
            int y2 = end.get(Calendar.YEAR);
            if (start.get(Calendar.YEAR) != y2) {
                start = (Calendar) start.clone();
                do {
                    days += start.getActualMaximum(Calendar.DAY_OF_YEAR);
                    start.add(Calendar.YEAR, 1);
                } while (start.get(Calendar.YEAR) != y2);
                
            }
            return days;
        }
        /**
         * 手動維護2016年的節假日
         * @since 1.0 
         * @return
         * @throws ParseException
         * <br><b>作者: @author zhushunagshuang</b>
         * <br>創建時間:2016年7月21日 下午5:12:08
         */
        public List<Date> initHoliday() throws ParseException{                
            List<Date> holidays = new ArrayList<Date>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //元旦
            holidays.add(sdf.parse("2016-01-01"));
            holidays.add(sdf.parse("2016-01-02"));
            holidays.add(sdf.parse("2016-01-03"));
            //春節
            holidays.add(sdf.parse("2016-02-07"));
            holidays.add(sdf.parse("2016-02-08"));
            holidays.add(sdf.parse("2016-02-09"));
            holidays.add(sdf.parse("2016-02-10"));
            holidays.add(sdf.parse("2016-02-11"));
            holidays.add(sdf.parse("2016-02-12"));
            holidays.add(sdf.parse("2016-02-13"));
            //清明節
            holidays.add(sdf.parse("2016-04-02"));
            holidays.add(sdf.parse("2016-04-03"));
            holidays.add(sdf.parse("2016-04-04"));
            //勞動節
            holidays.add(sdf.parse("2016-04-30"));
            holidays.add(sdf.parse("2016-05-01"));
            holidays.add(sdf.parse("2016-05-02"));
            //端午節
            holidays.add(sdf.parse("2016-06-09"));
            holidays.add(sdf.parse("2016-06-10"));
            holidays.add(sdf.parse("2016-06-11"));
            //中秋節
            holidays.add(sdf.parse("2016-09-15"));
            holidays.add(sdf.parse("2016-09-16"));
            holidays.add(sdf.parse("2016-09-17"));
            //國慶節
            holidays.add(sdf.parse("2016-10-01"));
            holidays.add(sdf.parse("2016-10-02"));
            holidays.add(sdf.parse("2016-10-03"));
            holidays.add(sdf.parse("2016-10-04"));
            holidays.add(sdf.parse("2016-10-05"));
            holidays.add(sdf.parse("2016-10-06"));
            holidays.add(sdf.parse("2016-10-07"));
            return holidays;
        }
        
}

 

貼出來。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved