欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OA请假自动计算请假时长(只计算工作日时长,剔除周末以及法定节假日等)

程序员文章站 2022-05-18 19:39:21
...

标题

作为一个刚开始进入编程工作的小白,这也是我的第一篇博客,其实这点业务对于大牛来说可能分分钟搞定的事,小白的我却花了2天擦搞定。
话不多少说,进正题!!!先说说我的业务需求:做了一个关于OA请假的流程申请,其中涉及了请假时长计算的问题,在前台选开始/结束时间,然后自动计算请假天数。其中8:30-11:30 13:30-17:30为工作时间,请假>=2小时为0天;2小时<时间<=4小时为0.5天;时间>4小时为1天。
其中除婚假,产假,探亲假外,只计算有效工作时间内的时长(系统自动剔除周末及法定节假日,调休等)!
此项目因为是之前老项目,所以用的Struts2,还有就是JSP里面使用好多公司封装的组件,所以大请假只拿自己有用的就好了!

前台jsp

function SumDays() {
	//关于前两行大家可以使用自己的获取两个时间(此处我是使用公司自己组件得到两个
	yyyy-mm-dd hh:mm:ss格式时间)
	var beginTime = ajaxform1.getColumnValue("beginTime");
	var endTime = ajaxform1.getColumnValue("endTime");
	//截取到月份
	var starttimeleft=beginTime.substring(0,10);
	var endtimeleft=endTime.substring(0,10);
	//获取毫秒数
	var bDate = (new Date(beginTime)).getTime();
	var eDate = (new Date(endTime)).getTime();
	if(eDate < bDate){
		setRM("error","结束日期不能小于开始日期! "); 
	}
	//次函数是获取两个时间量内所有的日期(jsp通用)
	function dateAll(startTimes,endTimes){
		var date_all=[],i=0;
	    function getDate(datestr){
	      var temp = datestr.split("-");
	      var date = new Date(temp[0],temp[1]-1,temp[2]);
	      return date;
	    }
	    var start = startTimes;
	    var end = endTimes;
	    var startTime = getDate(start);
	    var endTime = getDate(end);
	    while((endTime.getTime()-startTime.getTime())>=0){
	      var year = startTime.getFullYear();
	      var month = (startTime.getMonth()+1).toString().length==1?"0"+(startTime.getMonth()+1).toString():(startTime.getMonth()+1).toString();
	      var day = startTime.getDate().toString().length==1?"0"+startTime.getDate():startTime.getDate();
	      date_all[i]=year+"-"+month+"-"+day;
	      startTime.setDate(startTime.getDate()+1);
	      i+=1;
		 }
		 return date_all;
	}
	//得到两个日期内所有的日期
	var dates = "";
	var dateAll = dateAll(starttimeleft,endtimeleft);
	for(var i=0;i<dateAll.length;i++){
		dates += dateAll[i]+",";
	}
	//获取form表单内所有的数据
	var data = ajaxform1.collectData(true);
	var dataArr = [];
	dataArr.push(data);
	//回传到后台JAVA程序处理
	$.request({
		action : "check",
		data : dataArr,
		params : {
			dates : dates,
			beginTime : beginTime,
			endTime : endTime
			},
		success : ajax_init
	}) ;
}

后台JAVA

我的思路是:在后台得到前台传过来的选的开始/结束时间、两日期内所有的日期三个参数,循环遍历所有日期,再利用法定节假日接口,以此判断是否是节假日,周末等等。最终根据请假小时数计算天数

public void check() throws Exception{
		//得到form表单里的实体数据(此处大家可使用自己的,我使用的公司的封装体)
		SzglOaQj szglOaQj = dataWrap.getData();
		if (SzglCommonUtil.strIsNull(szglOaQj.getQjType())) {
			throw new BaseConfirmException("请先选择请假类型!");
		}
		//得到开始的小时
        Double starHour =Double.parseDouble( beginTime.substring(11, 13)+"."+beginTime.substring(14, 16));
        //得到结束的小时
        Double endHour =Double.parseDouble( endTime.substring(11, 13)+"."+endTime.substring(14, 16));
        //得到两日期内所有的日期
		List<String> dateList = SzglCommonUtil.paraseIdsStr(getDates());
		Double travelTimeHours = 0.0;
		//遍历所有日期
		for (int i = 0; i < dateList.size(); i++) {
			String date = dateList.get(i);
			/*此处调用了网上的法定节假日接口,大家靠自行查阅资料
			(返回的JSON格式的数据,常工作日对应结果为 0, 法定节假日对应结果为 1, 
			节假日调休补班对应的结果为 2,休息日对应结果为 3)*/
			String url="http://api.goseek.cn/Tools/holiday";
	        try {
	        	//最终s为JSON数据解析的值
	        	  String s = "";
	        	  String dateD = date.replace("-", "");
	              String request="date="+dateD;
	              //getData方法参阅下面
	              String response=getData(url,request);
	              JSONObject object = new JSONObject(response);
	              if (!object.isNull("data")) {
				  s = object.getString("data");
				  //判断是否是婚假、产假、探亲假
				  if (szglOaQj.getQjType().equals("05") || szglOaQj.getQjType().equals("08")
						  || szglOaQj.getQjType().equals("09")) {
						if(starHour < 8.30){
							starHour = 8.30;
						}
						if(starHour > 17.30){
							starHour = 17.30;
						}
						if(endHour < 8.30){
							endHour = 8.30;
						}
						if(endHour > 17.30){
							endHour = 17.30;
						}
						//如果为第一天则计算当天的请假小时数
						if (i == 0) {
							if (starHour <= 11.30) {
								travelTimeHours += (11.30-starHour+4);
							}else if (starHour > 11.30 && starHour < 13.30) {
								travelTimeHours += 4;
							}else if (starHour >= 13.30) {
								travelTimeHours += (17.30-starHour);
							}
						}
						//计算最后一天的请假小时数
						if (i == dateList.size()-1) {
							if (endHour <= 11.30) {
								travelTimeHours += (endHour-8.30);
							}else if (endHour > 11.30 && endHour < 13.30) {
								travelTimeHours += 3;
							}else if (endHour >= 13.30) {
								travelTimeHours += (endHour - 13.30 + 3.0);
							}
						}
						//中间的天直接计算7小时工作日
						if (i != 0 && i != dateList.size()-1) {
							travelTimeHours += 7;
						}
				}else {
					//只计算工作日内小时数
					if (s.equals("0")) {
						//是否是同一天(isSameDay方法放在了最后)
						if (SzglCommonUtil.isSameDay(beginTime, endTime)) {
							if (starHour <= 11.30) {
								if (8.30<= endHour && endHour<13.30) {
									if((endHour-starHour) <= 2){
										szglOaQj.setDays(new BigDecimal(0));
									}else if ((endHour-starHour) > 2) {
										szglOaQj.setDays(new BigDecimal(0.5));
									}
								}else if (endHour>13.30) {
									if(((endHour-starHour)-2)<=2){
										szglOaQj.setDays(new BigDecimal(0));
									}else if(2<((endHour-starHour)-2)&&((endHour-starHour)-2)<=4){
										szglOaQj.setDays(new BigDecimal(0.5));
									}else if(((endHour-starHour)-2) > 4){
										szglOaQj.setDays(new BigDecimal(1));
									}
								}
							}else if (starHour >= 13.30) {
								if((endHour-starHour) <= 2){
									szglOaQj.setDays(new BigDecimal(0));
								}else if((endHour-starHour) > 2){
									szglOaQj.setDays(new BigDecimal(0.5));
								}
							}
						}else {//如果不是同一天
							if(starHour < 8.30){
								starHour = 8.30;
							}
							if(starHour > 17.30){
								starHour = 17.30;
							}
							if(endHour < 8.30){
								endHour = 8.30;
							}
							if(endHour > 17.30){
								endHour = 17.30;
							}
							if (i == 0) {
								if (starHour <= 11.30) {
									travelTimeHours += (11.30-starHour+4);
								}else if (starHour > 11.30 && starHour < 13.30) {
									travelTimeHours += 4;
								}else if (starHour >= 13.30) {
									travelTimeHours += (17.30-starHour);
								}
							}
							if (i == dateList.size()-1) {
								if (endHour <= 11.30) {
									travelTimeHours += (endHour-8.30);
								}else if (endHour > 11.30 && endHour < 13.30) {
									travelTimeHours += 3;
								}else if (endHour >= 13.30) {
									travelTimeHours += (endHour - 13.30 + 3.0);
								}
							}
							if (i != 0 && i != dateList.size()-1) {
								travelTimeHours += 7;
							}
						}
					}
				}
			}
	       } catch (Exception e) {
	              e.printStackTrace();
	       }
		}
		/*根据所有小时数计算请假天数,取商则为天数,再取余判断是否超过了规定的小时数*/
		int times = (int) (travelTimeHours / 7);
		Double time =  (travelTimeHours % 7) ;
		if (time <= 2) {
			szglOaQj.setDays(new BigDecimal(times));
		}else if (2 < time && time <= 4) {
			szglOaQj.setDays(new BigDecimal(times+0.5));
		}else if (4 < time){
			szglOaQj.setDays(new BigDecimal(times+1));
		}
		//最终返回了前台显示
		dataWrap.setData(szglOaQj);
		responseData.setAjaxDataWrap("dataWrap", dataWrap);
	}
	//网上接口的调用需要发送请求,此处是发送请求方法
	public static String getData(String url, String request)throws UnsupportedEncodingException, IOException {
	       String charset = "UTF-8";
	       ByteArrayOutputStream outStream = new ByteArrayOutputStream();
	       HttpURLConnection connect = (HttpURLConnection) (new URL(url).openConnection());
	       connect.setRequestMethod("GET");
	       connect.setDoOutput(true);
	       connect.setConnectTimeout(1000 * 10);
	       connect.setReadTimeout(1000 * 80);
	       connect.setRequestProperty("ContentType",  "application/x-www-form-urlencoded"); //采用通用的URL百分号编码的数据MIME类型来传参和设置请求头
	       connect.setDoInput(true);
	       // 连接
	       connect.connect();
	       // 发送数据
	       connect.getOutputStream().write(request.getBytes(charset));
	       // 接收数据
	       int responseCode = connect.getResponseCode();
	       if (responseCode == HttpURLConnection.HTTP_OK) {
	       InputStream in = connect.getInputStream();
	       byte[] data = new byte[1024];
	       int len = 0;
	       while ((len = in.read(data, 0, data.length)) != -1) {
	              outStream.write(data, 0, len);
	       }
	              in.close();
	       }
	       // 关闭连接
	       connect.disconnect();
	       String response = outStream.toString("UTF-8");
	       return response;
	       }

是否是同一天的判断方法

public static boolean isSameDay(String day1, String day2) {
		String time1 = day1.substring(0, 10);
		String time2 = day2.substring(0, 10);
		if (time1.equals(time2)) {
			return true;
		}else {
			return false;
		}
	}

因为开发框架的原因,和大家的使用肯定有所不同,能用的拿走不谢,大家参考里面的思路就好了!

相关标签: java mysql