时效算法-给定开始时间和环节时效计算结束时间,考虑节假日、调休日和正常双休

感谢原博主的博文 https://blog.csdn.net/zjnxyz/article/details/17164369

我是在原博主的基础上优化了下,增加了法定节假日和调休日的手动维护工具类,在此记录一下,以便以后碰到类似问题。

维护工具类

/**
 * 手动维护法定节假日和法定调休日工具类
 * @author MaJian
 *
 */
public class InsertHolidayUtil {
 
    public static void main(String[] args){
        //驱动程序名
        String driver = "com.mysql.jdbc.Driver";
       // String driver = "oracle.jdbc.driver.OracleDriver";
        //要插入的数据库
        String url = "你的数据库连接地址";
        //String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
        String user = "用户名";
        String password = "密码";
        DriverManagerDataSource ds = new DriverManagerDataSource();       
        try {
            ds.setDriverClassName(driver);       
            ds.setUrl(url);       
            ds.setUsername(user);       
            ds.setPassword(password);
            Connection actualCon = ds.getConnection(); 
            Statement statement = actualCon.createStatement();
 
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date start = sdf.parse("2019-02-05");//开始时间
            Date end = sdf.parse("2020-12-31");//结束时间
            //List<Date> lists = dateSplit(start, end);
            List<Date> lists = new ArrayList<Date>();
            List<Date> holidays = getHolidays();
            List<Date> workDays = getWorkDays();
            //手动插入一个时间段的所有时间
            if (!lists.isEmpty()) {
                for (Date date : lists) {
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(date);
                    System.out.println("********插入日期:" + sdf.format(date) + "***********");
                    int week = cal.get(Calendar.DAY_OF_WEEK)-1;
                    String weekStr = "";
                    if(week == 0){
                        weekStr = "星期日";
                    }
                    if(week == 1){
                        weekStr = "星期一";
                    }
                    if(week == 2){
                        weekStr = "星期二";                  
                    }
                    if(week == 3){
                        weekStr = "星期三";
                    }
                    if(week == 4){
                        weekStr = "星期四";
                    }
                    if(week == 5){
                        weekStr = "星期五";
                    }
                    if(week == 6){
                        weekStr = "星期六";
                    }
                    String insertSql = "INSERT INTO mc_holiday (DAYLIST, WEEKLIST, IS_HOLIDAY, INCREMENT) " +
                            "VALUES('"+sdf.format(date)+"','"+weekStr+"','"+isHoliday(date)+"','')";
                    statement.execute(insertSql);
                }
            }
            //法定调休日
            if (!workDays.isEmpty()) {
                for (Date date : workDays) {
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(date);
                    System.out.println("********插入日期:" + sdf.format(date) + "***********");
                    int week = cal.get(Calendar.DAY_OF_WEEK)-1;
                    String weekStr = "";
                    if(week == 0){
                        weekStr = "星期日";
                    }
                    if(week == 1){
                        weekStr = "星期一";
                    }
                    if(week == 2){
                        weekStr = "星期二";                  
                    }
                    if(week == 3){
                        weekStr = "星期三";
                    }
                    if(week == 4){
                        weekStr = "星期四";
                    }
                    if(week == 5){
                        weekStr = "星期五";
                    }
                    if(week == 6){
                        weekStr = "星期六";
                    }
                    String insertSql = "INSERT INTO mc_holiday (DAYLIST, WEEKLIST, IS_HOLIDAY, INCREMENT) " +
                            "VALUES('"+sdf.format(date)+"','"+weekStr+"','0','"+sdf.format(date).substring(0,4)+"')";
                    statement.execute(insertSql);
                }
            }
            //法定节假日
            if (!holidays.isEmpty()) {
                for (Date date : holidays) {
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(date);
                    System.out.println("********插入日期:" + sdf.format(date) + "***********");
                    int week = cal.get(Calendar.DAY_OF_WEEK)-1;
                    String weekStr = "";
                    if(week == 0){
                        weekStr = "星期日";
                    }
                    if(week == 1){
                        weekStr = "星期一";
                    }
                    if(week == 2){
                        weekStr = "星期二";                  
                    }
                    if(week == 3){
                        weekStr = "星期三";
                    }
                    if(week == 4){
                        weekStr = "星期四";
                    }
                    if(week == 5){
                        weekStr = "星期五";
                    }
                    if(week == 6){
                        weekStr = "星期六";
                    }
                    String insertSql = "INSERT INTO mc_holiday (DAYLIST, WEEKLIST, IS_HOLIDAY, INCREMENT) " +
                             "VALUES('"+sdf.format(date)+"','"+weekStr+"','1','"+sdf.format(date).substring(0,4)+"')";
                    statement.execute(insertSql);
                }
            }
            actualCon.close();
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 法定节假日
     * @return
     */
    private static List<Date> getHolidays(){
        List<Date> holidays = new ArrayList<Date>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            //元旦
            holidays.add(sdf.parse("2018-01-01"));
            //春节
            holidays.add(sdf.parse("2018-02-15"));
            holidays.add(sdf.parse("2018-02-16"));
            holidays.add(sdf.parse("2018-02-17"));
            holidays.add(sdf.parse("2018-02-18"));
            holidays.add(sdf.parse("2018-02-19"));
            holidays.add(sdf.parse("2018-02-20"));
            holidays.add(sdf.parse("2018-02-21"));
            //清明
            holidays.add(sdf.parse("2018-04-05"));
            holidays.add(sdf.parse("2018-04-06"));
            holidays.add(sdf.parse("2018-04-07"));
            //劳动节
            holidays.add(sdf.parse("2018-04-29"));
            holidays.add(sdf.parse("2018-04-30"));
            holidays.add(sdf.parse("2018-05-01"));
            //端午节
            holidays.add(sdf.parse("2018-06-16"));
            holidays.add(sdf.parse("2018-06-17"));
            holidays.add(sdf.parse("2018-06-18"));
            //中秋节
            holidays.add(sdf.parse("2018-09-22"));
            holidays.add(sdf.parse("2018-09-23"));
            holidays.add(sdf.parse("2018-09-24"));
            //国庆节
            holidays.add(sdf.parse("2018-10-01"));
            holidays.add(sdf.parse("2018-10-02"));
            holidays.add(sdf.parse("2018-10-03"));
            holidays.add(sdf.parse("2018-10-04"));
            holidays.add(sdf.parse("2018-10-05"));
            holidays.add(sdf.parse("2018-10-06"));
            holidays.add(sdf.parse("2018-10-07"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return holidays;
    }
    /**
     * 法定调休日
     * @return
     */
    private static List<Date> getWorkDays(){
        List<Date> workDays = new ArrayList<Date>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            //春节
            workDays.add(sdf.parse("2018-02-11"));
            workDays.add(sdf.parse("2018-02-24"));
            //清明
            workDays.add(sdf.parse("2018-04-08"));
            //劳动节
            workDays.add(sdf.parse("2018-04-28"));
            //国庆节
            workDays.add(sdf.parse("2018-09-29"));
            workDays.add(sdf.parse("2018-09-30"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return workDays;
    }
    
    private static List<Date> dateSplit(Date start, Date end) throws Exception {
        if (!start.before(end))
            throw new Exception("开始时间应该在结束时间之后");
        Long spi = end.getTime() - start.getTime();
        int step = (int) (spi / (24 * 60 * 60 * 1000));// 相隔天数
        List<Date> dateList = new ArrayList<Date>();
        dateList.add(start);
        for (int i = 0; i < step; i++) {
            dateList.add(new Date(dateList.get(i).getTime() + (24 * 60 * 60 * 1000)));// 比上一天减一
        }
        return dateList;
    }
 
    /**
     * 判断是否为节假日,若是返回1,否则返回0
     * @param date
     * @return
     */
    private static int isHoliday(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        List<Date> holidays = getHolidays();
        List<Date> workdays = getWorkDays();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//        System.out.println(sdf.format(date));
        if(((cal.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY||cal.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY)&&!workdays.contains(sdf.format(date))) || holidays.contains(sdf.format(date)) ) {
            return 1;
        }
        return 0;
    }
 
    private static Date getLastWorkDay(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH,-1);
        Date dateTemp = cal.getTime();
 
        while (isHoliday(dateTemp) != 0){
            cal.add(Calendar.DAY_OF_MONTH,-1);
            dateTemp = cal.getTime();
        }
        return dateTemp;
    }

下面是时限计算和时间段相差的逻辑代码,工作时间可以从数据库或配置文件取,这样可以更灵活

public class DateCal {

    //工作时间
    private String morningBegin = "08:30";//上午开始时间
    private String morningEnd = "12:00";//上午结束时间
    private String afternoonBegin = "14:00";//下午开始时间
    private String afternoonEnd  = "18:00";//结束时间
    /**
     * 根据日期计算xx小时后对应日期,刨除工作日、节假日
     *
     * @param d
     * @param hours
     * @return
     */
    public Date getPluseHourDate(Date d, double hours){
        Calendar cal_start = Calendar.getInstance();
        cal_start.setTime(d);
        return func(cal_start, hours);
    }
    /**
     * 计算两个日期之间的时间差,不算节假日、不算周末、不算非正常工作时间
     * <p>
     * 设计思路:
     * 取开始时间,判断是否是节假日、是否是周末、是否是加班日
     * 如果是节假日:
     * 往后+1天,再继续判断
     * 如果是周末:
     * 判断是否是加班日,如果不是加班日,往后+1天
     *
     * @param begin 开始时间
     * @param end   结束时间
     * @return 时间差,单位是毫秒
     */
    public long getMinusofTowDate(Calendar begin, Calendar end){
        long midL = 0;//中间差值时间
        // 0.预处理
        begin = getBeginDay(begin);
        end = getEndDay(end);
        // 1.如果开始时间大于结束时间,交换下,同时结果返回负数即可
        if (begin.after(end)){
            Calendar swap = begin;
            begin = end;
            end = swap;
            midL = -getDayMiLLI(begin, end);
        }else{
            midL = getDayMiLLI(begin, end);
        }
        // 2.计算开始
        return midL;
    }
    /**
     * 判断是否是法定节假日
     * 关于法定节假日,这里还有一个问题需要提前考虑下
     * 例如:
     * 国庆10月1号到10月7号,那10月8号正式上班,但是如果10月8号是周日,在计算的时候,也会不考虑进去。这就比较尴尬。
     * 另外就是10月8号是不是周末,不同年份又不同。
     * 处理办法:
     * 把可能产生上述问题的日期,都单独拎出来,在计算的时候,先判断是否满足这些日期,再判断这些日期是否是周末
     * 如果不是周末,正常计算,如果是周末,还要加上当天的时间。
     * @param d1
     * @return
     */
    private boolean isHodliDays(Calendar d1){
	    //法定节假日,当然这个地方是从数据库里取出来的
        private String isHoliday = "2018-09-22,2018-09-23,2018-09-24,2018-10-01,2018-10-02,2018-10-03,2018-10-04,2018-10-05,2018-10-06,2018-10-07";
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    	String time = format.format(d1.getTime());
        //String str = String.valueOf(d1.get(Calendar.MONTH) + 1) + "-" + String.valueOf(d1.get(Calendar.DAY_OF_MONTH));
        if (isHoliday.contains(time)){
            return true;
        }
        return false;
    }

    //判断是否是加班日
    private boolean isPlusDay(Calendar d1){
        //节假日前后的加班,当然这个地方是从数据库里取出来的
        private String isPlusDau = "2018-09-29,2018-09-30";
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    	String time = format.format(d1.getTime());
        //String str = String.valueOf(d1.get(Calendar.MONTH) + 1) + "-" + String.valueOf(d1.get(Calendar.DAY_OF_MONTH));
        if (isPlusDau.contains(time)){
            return true;
        }
        return false;
    }

    //判断是否是周末
    private boolean isWeek(Calendar d1){
        if (d1.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || d1.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){
            return true;
        }
        return false;
    }

    //预处理开始时间
    private Calendar getBeginDay(Calendar d1){
        if (isHodliDays(d1)){
            //如果是节假日,往后延一天,并且从这一天的00:00:00开始
            d1 = addCalendar(d1, 1);
            return getBeginDay(d1);
        }else{
            //再判断是否是周末,如果是周末,判断是否是加班日
            if (isWeek(d1)){
                if (!isPlusDay(d1)){
                    d1 = addCalendar(d1, 1);
                    return getBeginDay(d1);
                }else{
                    return d1;
                }
            }
            else{
                return d1;
            }
        }
    }

    //预处理结束时间
    private Calendar getEndDay(Calendar d2){
        if (isHodliDays(d2)){
            //如果是节假日,往前提一天,并且从这一天的00:00:00开始
            d2 = addCalendar(d2, -1);
            return getEndDay(d2);
        }else{
            //不是节假日
            if (isWeek(d2)){
                if (!isPlusDay(d2)){
                    d2 = addCalendar(d2, -1);
                    return getEndDay(d2);
                }else{
                    return d2;
                }
            }
            else{
                return d2;
            }
        }
    }

    //预处理重置时分秒
    private Calendar addCalendar(Calendar d, int m){
        if (m == 1){
            d.add(Calendar.DATE, 1);
            d.set(Calendar.HOUR_OF_DAY, 0);//也可直接设置为beginHour
            d.set(Calendar.MINUTE, 0);
            d.set(Calendar.SECOND, 0);
        }else{
            d.add(Calendar.DATE, -1);
            d.set(Calendar.HOUR_OF_DAY, 23);//也可直接设置为endHour
            d.set(Calendar.MINUTE, 59);
            d.set(Calendar.SECOND, 59);
        }
        return d;
    }
   /* private boolean compareTimes(String time1,String time2){
    	try {
    		SimpleDateFormat sdf=new SimpleDateFormat("hh:mm");
    		//将字符串形式的时间转化为Date类型的时间
    		Date a=sdf.parse(time1);
    		Date b=sdf.parse(time2);
        	if(a.before(b)){
        		return true;
        	}else{
        		return false;
        	}
		} catch (Exception e) {
			e.printStackTrace();
		}
    	return true;
    }*/
    //获取当天实际的工作时间
    private long getDayMiLLI(Calendar d, boolean isBegin){
        long rv = 0;
        int  h = d.get(Calendar.HOUR_OF_DAY);
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
    	String time = format.format(d.getTime());
    	try {
			Date hTime = format.parse(time);
			Date mgBegin = format.parse(morningBegin);
			Date mgEnd = format.parse(morningEnd);
			Date afBegin = format.parse(afternoonBegin);
			Date afend = format.parse(afternoonEnd);
	        if (isBegin){
	            if (hTime.getTime() < afend.getTime()){
	                if (hTime.getTime() >= mgBegin.getTime()){
	                    if (hTime.getTime() >= afBegin.getTime()){
	                        //计算开始那一天的时间长度
	                        rv += afend.getTime() - hTime.getTime();
	                       // rv -= d.get(Calendar.MINUTE) * 60 * 1000;
	                        rv -= d.get(Calendar.SECOND) * 1000;
	                        rv -= d.get(Calendar.MILLISECOND);
	                    }else if (hTime.getTime() >= mgEnd.getTime() && hTime.getTime() < afBegin.getTime()){
	                        rv += afend.getTime() - afBegin.getTime();
	                    }else{
	                        rv += (afend.getTime() - afBegin.getTime()) + (mgEnd.getTime() - hTime.getTime());
	                        //rv -= d.get(Calendar.MINUTE) * 60 * 1000;
	                        rv -= d.get(Calendar.SECOND) * 1000;
	                        rv -= d.get(Calendar.MILLISECOND);
	                    }
	                }else{
	                    rv = (afend.getTime() - afBegin.getTime()) + (mgEnd.getTime() - mgBegin.getTime());
	                }
	            }
	        }else{
	            if (hTime.getTime() >= mgBegin.getTime()){
	                if (hTime.getTime() < afend.getTime()){
	                    if (hTime.getTime() >= afBegin.getTime()){
	                        rv += (mgEnd.getTime() - mgBegin.getTime()) + (hTime.getTime() - afBegin.getTime());
	                        //rv += d.get(Calendar.MINUTE) * 60 * 1000;
	                        rv += d.get(Calendar.SECOND) * 1000;
	                        rv += d.get(Calendar.MILLISECOND);
	                    }else if (hTime.getTime() >= mgEnd.getTime() && hTime.getTime() < afBegin.getTime()){
	                        rv += mgEnd.getTime() - mgBegin.getTime();
	                    }else{
	                        rv += hTime.getTime() - mgBegin.getTime();
	                        //rv += d.get(Calendar.MINUTE) * 60 * 1000;
	                        rv += d.get(Calendar.SECOND) * 1000;
	                        rv += d.get(Calendar.MILLISECOND);
	                    }
	                }else{
	                    rv = (afend.getTime() - afBegin.getTime()) + (mgEnd.getTime() - mgBegin.getTime());
	                }
	            }
	        }
    	} catch (ParseException e) {
			e.printStackTrace();
		}
        return rv;
    }

    //核心计算函数,返回毫秒
    private long getDayMiLLI(Calendar c1, Calendar c2){
        long beginL = 0;//开始天时间
        long endL   = 0;//结束天时间
        long rv     = 0;
        //int bh = c1.get(Calendar.HOUR_OF_DAY);//开始
        //int eh = c2.get(Calendar.HOUR_OF_DAY);//结束
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
    	String bhTime = format.format(c1.getTime());
    	String ehTime = format.format(c2.getTime());
    	try {
    		Date bh = format.parse(bhTime);
    		Date eh = format.parse(ehTime);
			Date mgBegin = format.parse(morningBegin);
			Date mgEnd = format.parse(morningEnd);
			Date afBegin = format.parse(afternoonBegin);
			Date afend = format.parse(afternoonEnd);
	        //如果开始日期和结束日期不是同一天,开始往前计算
	        if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR) || c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH) || c1.get(Calendar.DAY_OF_MONTH) != c2.get(Calendar.DAY_OF_MONTH)){
	            //不是同一天
	            beginL = getDayMiLLI(c1, true);
	            endL = getDayMiLLI(c2, false);
	            rv = beginL + endL;
	            c1.add(Calendar.DATE, 1);
	            while (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR) || c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH) || c1.get(Calendar.DAY_OF_MONTH) != c2.get(Calendar.DAY_OF_MONTH)){
	                if (!isHodliDays(c1)){
	                    if (!isWeek(c1)){
	                        rv += (afend.getTime() - afBegin.getTime()) + (mgEnd.getTime() - mgBegin.getTime());
	                    }else{
	                        if (isPlusDay(c1)){
	                            rv += (afend.getTime() - afBegin.getTime()) + (mgEnd.getTime() - mgBegin.getTime());
	                        }
	                    }
	                }
	                c1.add(Calendar.DATE, 1);
	            }
	        }else{
	        	//是同一天
	            if (bh.getTime() < mgBegin.getTime()){
	                //开始时间小于早上开始时间,就等于说及计算结束时间在这一天的实际时间
	                rv += getDayMiLLI(c2, false);
	            }else{
	                if (eh.getTime() >= afend.getTime()){
	                    //结束时间大于下午结束时间,等于就是计算开始时间在这一天的实际时间
	                    rv += getDayMiLLI(c1, true);
	                }else{
	                    /**
	                     * 开始和结束都在中间时间段
	                     * 1.开始和结束都在上午
	                     * 2.开始和结束都在下午
	                     * 3.开始在上午,结束在下午
	                     * 4.开始在中间,结束不在
	                     * 5.结束在中间,开始不在
	                     * 6.开始和结束都在中间
	                     */
	
	                    if (eh.getTime() < mgEnd.getTime() || bh.getTime() >= afBegin.getTime()){
	                        //都在上午或者都在下午
	                        rv += eh.getTime() - bh.getTime();
	                        //rv -= c1.get(Calendar.MINUTE) * 60 * 1000;
	                        rv -= c1.get(Calendar.SECOND) * 1000;
	                        rv -= c1.get(Calendar.MILLISECOND);
	                        //rv += c2.get(Calendar.MINUTE) * 60 * 1000;
	                        rv += c2.get(Calendar.SECOND) * 1000;
	                        rv += c2.get(Calendar.MILLISECOND);
	                    }else if (bh.getTime() < mgEnd.getTime() && eh.getTime() >= afBegin.getTime()){
	                        //开始在上午,结束在下午
	                        rv += (eh.getTime() - bh.getTime()) - (afBegin.getTime() - mgEnd.getTime());
	                        //rv -= c1.get(Calendar.MINUTE) * 60 * 1000;
	                        rv -= c1.get(Calendar.SECOND) * 1000;
	                        rv -= c1.get(Calendar.MILLISECOND);
	                        //rv += c2.get(Calendar.MINUTE) * 60 * 1000;
	                        rv += c2.get(Calendar.SECOND) * 1000;
	                        rv += c2.get(Calendar.MILLISECOND);
	                    }else if (bh.getTime() < mgEnd.getTime() && eh.getTime() < afBegin.getTime()){
	                        //开始在上午,结束在中间
	                        rv += mgEnd.getTime() - bh.getTime();
	                       // rv -= c1.get(Calendar.MINUTE) * 60 * 1000;
	                        rv -= c1.get(Calendar.SECOND) * 1000;
	                        rv -= c1.get(Calendar.MILLISECOND);
	                    }else if (bh.getTime() > mgEnd.getTime() && eh.getTime() >= afBegin.getTime()){
	                        //开始在中间,结束在下午
	                        rv += eh.getTime() - afBegin.getTime();
	                        //rv += c2.get(Calendar.MINUTE) * 60 * 1000;
	                        rv += c2.get(Calendar.SECOND) * 1000;
	                        rv += c2.get(Calendar.MILLISECOND);
	                    }else{
	                       System.out.println("the begin time c1 " + c1.toString() + " and the end time c2 " + c2.toString() + " in not work day!");
	                    }
	                }
	            }
	        }
    	} catch (ParseException e) {
			e.printStackTrace();
		}
        return rv;
    }

    private Calendar getNew(Calendar begin){
        begin.add(Calendar.DATE, 1);
        begin.set(Calendar.HOUR_OF_DAY, Integer.valueOf(morningBegin.substring(0,2)));
        begin.set(Calendar.MINUTE, Integer.valueOf(morningBegin.substring(3,5)));
        begin.set(Calendar.SECOND, 0);
        return begin;
    }

    //核心计算函数,返回日期
    private Date func(Calendar begin, double hours){
        begin = getBeginDay(begin);
        //int h = begin.get(Calendar.HOUR_OF_DAY);
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
    	String bhTime = format.format(begin.getTime());
    	try {
    		Date h = format.parse(bhTime);
			Date mgBegin = format.parse(morningBegin);
			Date mgEnd = format.parse(morningEnd);
			Date afBegin = format.parse(afternoonBegin);
			Date afEnd = format.parse(afternoonEnd);
	        if (h.getTime() < mgBegin.getTime()){
	            //全天
	            if (hours > (((afEnd.getTime() - afBegin.getTime())/(double)3600000) + ((mgEnd.getTime() - mgBegin.getTime())/(double)3600000))){
	                begin = getNew(begin);
	                hours = hours - (((afEnd.getTime() - afBegin.getTime())/(double)3600000) + ((mgEnd.getTime() - mgBegin.getTime()))/(double)3600000);
	                return func(begin, hours);
	            }else{
	                /**
	                 * 这里要判断下,这个小时是否大于上午的工作时间,大于的话,时间就的到下午去了
	                 */
	                if (hours > ((mgEnd.getTime() - mgBegin.getTime())/(double)3600000)){
	                    begin.set(Calendar.HOUR_OF_DAY, Integer.valueOf(afternoonBegin.substring(0,2)));
	                    begin.set(Calendar.MINUTE, Integer.valueOf(afternoonBegin.substring(3,5)));
	                    hours = hours - ((mgEnd.getTime() - mgBegin.getTime())/(double)3600000);
	                }else{
	                    begin.set(Calendar.HOUR_OF_DAY, Integer.valueOf(morningBegin.substring(0,2)));
	                    begin.set(Calendar.MINUTE, Integer.valueOf(morningBegin.substring(3,5)));
	                }
	                //begin.set(Calendar.MINUTE, 0);
	                begin.set(Calendar.SECOND, 0);
	                begin.set(Calendar.MILLISECOND, 0);
	                long time = begin.getTime().getTime();
	                hours = hours * 60 * 60 * 1000;
	                time += hours;
	                return new Date(time);
	            }
	        }else if (h.getTime() >= afEnd.getTime()){
	            //过期,新增一天,重新算
	            begin.add(Calendar.DATE, 1);
	            return func(begin, hours);
	        }else{
	            //计算
	            long tm = getDayMiLLI(begin, true);//今天的时间
	            double houts_m = hours * 60 * 60 * 1000;
	            if (tm >= houts_m){
	                //不跨天,计算今天的
	                if (h.getTime() < mgEnd.getTime()){
	                    //在上午
	                    long rv = 0;
	                    rv += mgEnd.getTime() - h.getTime();
	                    //rv -= begin.get(Calendar.MINUTE) * 60 * 1000;
	                    rv -= begin.get(Calendar.SECOND) * 1000;
	                    rv -= begin.get(Calendar.MILLISECOND);
	                    if (houts_m > rv){
	                        //到下午
	                        begin.set(Calendar.HOUR_OF_DAY, Integer.valueOf(afternoonBegin.substring(0,2)));
		                    begin.set(Calendar.MINUTE, Integer.valueOf(afternoonBegin.substring(3,5)));
	                        begin.set(Calendar.SECOND, 0);
	                        begin.set(Calendar.MILLISECOND, 0);
	                        long time = begin.getTime().getTime();
	                        time += (houts_m - rv);
	                        return new Date(time);
	                    }else{
	                        //还在上午
	                        long time = begin.getTime().getTime();
	                        time += houts_m;
	                        return new Date(time);
	                    }
	                }else if (h.getTime() >= afBegin.getTime()){
	                    //在下午
	                    long time = begin.getTime().getTime();
	                    time += houts_m;
	                    return new Date(time);
	                }else{
	                    //在中间
	                	begin.set(Calendar.HOUR_OF_DAY, Integer.valueOf(afternoonBegin.substring(0,2)));
		                begin.set(Calendar.MINUTE, Integer.valueOf(afternoonBegin.substring(3,5)));
	                    begin.set(Calendar.SECOND, 0);
	                    begin.set(Calendar.MILLISECOND, 0);
	                    long time = begin.getTime().getTime();
	                    time += houts_m;
	                    return new Date(time);
	                }
	            }else{
	                //跨天,到第二天
	                begin = getNew(begin);
	                hours = (houts_m - tm) / (double)3600000;
	                return func(begin, hours);
	            }
	        }
    	}catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
    }

修改的部分是支持了不是整点上下班的问题。

猜你喜欢

转载自blog.csdn.net/majian19901021/article/details/83617625