Java 计算工作时间 除去周末、节假日

需求:

1、给定两个时间 计算两个时间之间的工作小时数.
2、给出一个开始时间startDate,计算其加上x小时之后的时间.
(只考虑到了分钟,秒不计)

前提:

1、节假日及周末日期存放在数据库

源码:


public class CalculateHoursUtil {
	
	//设置上班时间:该处时间可以根据实际情况进行调整
	static float morningBegin = 9;//上午上班时间,小时
	static float morningEnd = 12.5f;//上午下班时间,小时
	static float eveningBegin = 14;//下午上班时间,小时
	static float eveningEnd = 18;//下午下班时间,小时

	static float noonBreak = eveningBegin-morningEnd;//中午休息时间
	static float eveningBreak = 24-eveningEnd+morningBegin;//晚上休息时间
	static float morningWork = morningEnd-morningBegin;//上午上班时间
	static float eveningWork = eveningEnd-eveningBegin;//下午上班时间
	static float operHours = morningWork + eveningWork;//一天上班时间
	

	
    @SuppressWarnings("deprecation")
	public static String findHours(List<HolidayTable> maps,String startDate,float time) {
		//用于格式化日期
		Date startTime =  TimeUtils.formatDate(startDate, "yyyy-MM-dd HH:mm:ss");
		Date endTime = null;
		//从数据库得到节假日的日期
	    //从startTime开始循环,若该日期不是节假日或者不是周六日则请假天数+1
	    Date flag = startTime;//设置循环开始日期
	    
	    Calendar cal = Calendar.getInstance();

	    cal.setTime(flag);
	    outer:while(time/operHours >= 1) {
	        for (HolidayTable map : maps){
	            if((TimeUtils.formatDate(TimeUtils.formatDate(flag),"yyyy-MM-dd")).compareTo(map.getHoliday()) == 0){
	            	//跳出循环进入下一个日期
	            	cal.add(Calendar.DAY_OF_MONTH, +1);
	                flag = cal.getTime();
	                continue outer;
	            }
	        }
	        //日期往后加一天
	        cal.add(Calendar.DAY_OF_MONTH, +1);
	        flag = cal.getTime();
	        time = time-operHours;
	    }
	    

	    float startHours = flag.getHours() + (float)flag.getMinutes()/60;
	    Date start =  TimeUtils.formatDate(TimeUtils.formatDate(flag),"yyyy-MM-dd");
    	cal.setTime(start);

	    //时间在上午上班之前
	    if(startHours <= morningBegin) {
    		if((time + morningBegin) <= morningEnd) {
	    		time = time + morningBegin ;
	    	} else if((time + morningBegin + noonBreak) <= eveningEnd) {
	    		time = time + morningBegin + noonBreak;
	    	} else {
	    		if((time + morningBegin + noonBreak + eveningBreak) <= morningEnd + 24) {
	    			time = time + morningBegin + noonBreak + eveningBreak;
	    		} else {
	    			time = time + morningBegin + noonBreak + eveningBreak + noonBreak;
	    		}
	    	}
    	}
	    //时间在上午上班时间
	    if(startHours > morningBegin && startHours <= morningEnd) {
	    	//结束时间在工作时间内  判断开始时间是否在上班时间之后
	    	if((time + startHours) <= morningEnd) {
	    		time = time + startHours;
	    	} else if((time + startHours + noonBreak) <= eveningEnd) {
	    		time = time + startHours + noonBreak;
	    	} else {
	    		if((time + startHours + noonBreak + eveningBreak) <= morningEnd + 24) {
	    			time = time + startHours + noonBreak + eveningBreak;
	    		} else {
	    			time = time + startHours + noonBreak + eveningBreak + noonBreak;
	    		}
	    	}
	    }
	    //时间在中午休息时间则取上午上班时间
	    if(startHours > morningEnd && startHours <= eveningBegin) {
	    	if((time + eveningBegin) <= eveningEnd) {
	    		time = time + eveningBegin;
	    	} else {
	    		if((time + eveningBegin + eveningBreak) <= morningEnd + 24) {
	    			time = time + eveningBegin + eveningBreak;
	    		} else {
	    			time = time + eveningBegin + eveningBreak + noonBreak;
	    		}
	    	}
	    }
	    //时间在中午休息时间则取上午上班时间
	    if(startHours > eveningBegin && startHours <= eveningEnd) {
	    	if((time + startHours) <= eveningEnd) {
	    		time = time + startHours;
	    	} else {
	    		if((time + startHours + eveningBreak) <= morningEnd + 24) {
	    			time = time + startHours + eveningBreak;
	    		} else {
	    			time = time + startHours + eveningBreak + noonBreak;
	    		}
	    	}
	    }
	    //时间大于中午休息时间则减去中午休息时间
	    if(startHours > eveningEnd) {
        	cal.add(Calendar.DAY_OF_MONTH, +1);
	    	if((time + morningBegin) <= morningEnd) {
	    		time = time + morningBegin ;
	    	} else if((time + morningBegin + noonBreak) <= eveningEnd) {
	    		time = time + morningBegin + noonBreak;
	    	} else {
	    		if((time + morningBegin + noonBreak + eveningBreak) <= morningEnd + 24) {
	    			time = time + morningBegin + noonBreak + eveningBreak;
	    		} else {
	    			time = time + morningBegin + noonBreak + eveningBreak + noonBreak;
	    		}
	    	}
	    }
	    
	    cal.add(Calendar.MINUTE, (int)(time*60));
	    endTime = cal.getTime();
	    //除去节假日
	    for (HolidayTable map : maps){
            if((TimeUtils.formatDate(TimeUtils.formatDate(endTime),"yyyy-MM-dd")).compareTo(map.getHoliday()) == 0){
            	//跳出循环进入下一个日期
            	cal.add(Calendar.DAY_OF_MONTH, +1);
            	endTime = cal.getTime();
                continue;
            }
        }
	    
	    System.out.println("-------endTime----:"+TimeUtils.formatDate(endTime));
		return TimeUtils.formatDate(endTime);
	}
	
    
    @SuppressWarnings("deprecation")
	public static float findOperHours(List<Date> maps,String startDate, String endDate) {
		//用于格式化日期
		Date startTime = TimeUtils.formatDate(startDate);
		Date endTime = TimeUtils.formatDate(endDate);
	    double leaveDays = 0;
	    //从startTime开始循环,若该日期不是节假日或者不是周六日则请假天数+1
	    Date flag = startTime;//设置循环开始日期
	    Calendar cal = Calendar.getInstance();

	    //如果结束时间大于开始时间则返回0
	    if(flag.compareTo(endTime) == 1) {
	    	return 0;
	    }
	    
	    outer:while((TimeUtils.formatDate(TimeUtils.formatDate(flag),"yyyy-MM-dd")).compareTo((TimeUtils.formatDate(TimeUtils.formatDate(endTime),"yyyy-MM-dd"))) == -1){
	        cal.setTime(flag);
	        for (Date map : maps){
                if((TimeUtils.formatDate(TimeUtils.formatDate(flag),"yyyy-MM-dd")).compareTo(map.getHoliday()) == 0){
                	//跳出循环进入下一个日期
                	cal.add(Calendar.DAY_OF_MONTH, +1);
                    flag = cal.getTime();
                    continue outer;
                }
	        }
	        leaveDays = leaveDays + operHours;
	        //日期往后加一天
	        cal.add(Calendar.DAY_OF_MONTH, +1);
	        flag = cal.getTime();
	    }
	    System.out.println("endTime.getHours()---"+endTime.getHours() +"------flag.getMinutes():" +flag.getMinutes());
	    float endHours = endTime.getHours() + (float)endTime.getMinutes()/60;
	    float startHours = flag.getHours() + (float)flag.getMinutes()/60;
	    
	    //时间在上午上班时间
	    if(endHours > morningBegin && endHours < morningEnd) {
	    	//结束时间在工作时间内  判断开始时间是否在上班时间之后
	    	if(startHours > morningBegin) {
	    		leaveDays = leaveDays + endHours - startHours;
	    	} else {
	    		leaveDays = leaveDays + endHours - morningBegin;
	    	}
	    }
	    //时间在中午休息时间则取上午上班时间
	    if(endHours > morningEnd && endHours < eveningBegin) {
	    	if(startHours < morningBegin) {
	    		leaveDays = leaveDays + morningEnd - morningBegin;
	    	} else if(startHours > morningBegin && startHours < morningEnd) {
	    		leaveDays = leaveDays + morningEnd - startHours;
	    	}
	    }
	    //时间大于中午休息时间则减去中午休息时间
	    if(endHours > eveningBegin) {
	    	if(startHours < morningBegin) {
	    		leaveDays = leaveDays + endHours - morningBegin - noonBreak;
	    	} else if(startHours > morningBegin && startHours < morningEnd) {
	    		leaveDays = leaveDays + endHours - startHours - noonBreak;
	    	} else if(startHours > morningEnd && startHours < eveningBegin) {
	    		leaveDays = leaveDays + endHours - eveningBegin;
	    	} else if(startHours > eveningBegin) {
	    		leaveDays = leaveDays + endHours - startHours;
	    	}
	    }
	    //时间大于晚上下班时间则去白天上班时间
	    if(endHours > eveningEnd) {
	    	if(startHours < morningBegin) {
	    		leaveDays = leaveDays + eveningEnd - morningBegin - noonBreak;
	    	} else if(startHours > morningBegin && startHours < morningEnd) {
	    		leaveDays = leaveDays + eveningEnd - startHours - noonBreak;
	    	} else if(startHours > morningEnd && startHours < eveningBegin) {
	    		leaveDays = leaveDays + eveningEnd - eveningBegin;
	    	} else if(startHours > eveningBegin) {
	    		leaveDays = leaveDays + eveningEnd - startHours;
	    	}
	    }
	    
	    System.out.println("-------leaveDays----:"+leaveDays);
		return (float)(Math.round(leaveDays*100)/100.0);
	}
	
}

 

测试代码:


public class Test_Holiday {
		@Test
        public void findOperHours() throws ParseException {
    		
        	float leaveDays = CalculateHoursUtil.findOperHours(initHoliday(),"2019-03-28 10:10:12", "2019-03-28 16:40:16");
    	    System.out.println("-------leaveDays----:"+leaveDays);
        	String endDate = CalculateHoursUtil.findHours(initHoliday(),"2019-03-28 10:00:00",4.5f);
    	    System.out.println("-------endDate----:"+endDate);
    	}


		/**
         * 手动维护2019年的节假日(由于测试 这里只写几个)
         * @since 1.0 
         * @return
         * @throws ParseException
         * <br><b>作者: @author ganyu</b>
         * <br>创建时间:2019年3月1日 下午5:12:08
         */
        public List<Date> initHoliday() throws ParseException{                
            List<Date> holidays = new ArrayList<Date>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            holidays.addsdf.parse("2019-01-01");
			holidays.addsdf.parse("2019-01-05");
			holidays.addsdf.parse("2019-01-06");
			holidays.addsdf.parse("2019-01-12");
			holidays.addsdf.parse("2019-01-13");
			holidays.addsdf.parse("2019-01-19");
			holidays.addsdf.parse("2019-01-20");
			holidays.addsdf.parse("2019-01-26");
			holidays.addsdf.parse("2019-01-27");
			holidays.addsdf.parse("2019-02-04");
			holidays.addsdf.parse("2019-02-05");
			holidays.addsdf.parse("2019-02-06");
			holidays.addsdf.parse("2019-02-07");
			holidays.addsdf.parse("2019-02-08");
			holidays.addsdf.parse("2019-02-09");
			holidays.addsdf.parse("2019-02-10");
			holidays.addsdf.parse("2019-02-16");
			holidays.addsdf.parse("2019-02-17");
			holidays.addsdf.parse("2019-02-23");
			holidays.addsdf.parse("2019-02-24");
			holidays.addsdf.parse("2019-03-02");
			holidays.addsdf.parse("2019-03-03");
			holidays.addsdf.parse("2019-03-09");
			holidays.addsdf.parse("2019-03-10");
			holidays.addsdf.parse("2019-03-16");
			holidays.addsdf.parse("2019-03-17");
			holidays.addsdf.parse("2019-03-23");
			holidays.addsdf.parse("2019-03-24");
			holidays.addsdf.parse("2019-03-30");
			holidays.addsdf.parse("2019-03-31");
			holidays.addsdf.parse("2019-04-05");
			holidays.addsdf.parse("2019-04-06");
			holidays.addsdf.parse("2019-04-07");
			holidays.addsdf.parse("2019-04-13");
			holidays.addsdf.parse("2019-04-14");
			holidays.addsdf.parse("2019-04-20");
			holidays.addsdf.parse("2019-04-21");
			holidays.addsdf.parse("2019-04-27");
			holidays.addsdf.parse("2019-04-28");
            return holidays;
        }
}

第一次写博客,如有问题,请批评指正!


版权声明:本文为gust150原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。