目录

1.假设上班时间如下:

2.请假时间计算方式:

3.请假可能存在的情况:

4.实现思路:

5.代码奉上,只需传入时间参数


1.假设上班时间如下:

  1.   上班时间为:08:30:00
  2.   中午休息时间为:12:00:00 到13:30:00
  3.   下班时间:18:00:00
  4.   每次请假必须至少请假半天(例如:08:30到12:00算0.5天   12:00到18:00算0.5天) 以上  
  5.   支持2019和2020年国家法定节假日,其他年份请自行添加

2.请假时间计算方式:

  任选两个时间段(无论是从周末、国家节假日开始请假  到  周末、国家节假日结束请假  都支持) 

    2.1.去掉周六周末(但是国家调休的有些班是在周六周末 所以要做判断,如果周六或者周末 是国家规定调休的班,那么就不能去掉,否则去掉)

    2.2.去掉国家法定节假日

    

3.请假可能存在的情况:

   3.1. 请假日期和结束日期相同(同一天)  例如:2019-12-1008:30:00  -  2019-12-1012:00:00   

   3.2 .请假日期和结束日期相邻(相邻的两天)例如:2019-12-1008:30:00  -  2019-12-11 12:00:00

   3.3.请假日期和结束日期不相邻(中间有间隔)例如:2019-12-10 08:30:00  -  2019-12-13 12:00:00

4.实现思路:

    分三部分计算各自的请假时间,相加即可

      第一部分:请假的当天的请假总时间(要么是半天,要么是一天)

      第二部分:请假的中间的请假总时间(不包含第一部分和第三部分)  

      第三部分:结束的当天的请假总时间(要么是半天,要么是一天)

5.代码奉上,只需传入时间参数

/**
	 * @param startTime Java接受的格式:Sun Dec 08 08:30:00 GMT+08:00 2019  
	  *                 前端传的格式是  2019-12-08 08:30:00
	 *                                                
	 * @param endTime   和startTime格式是一样的
	 * 
	 * @return 返回Map对象   key:leaveDays   value:就是计算结果
	 * 
	 *  代码比较新鲜,没有来得及做重构,欢迎大家重构
	 * @throws Exception
	 */
	@RequestMapping(value = "calcLeaveTime")
	@ResponseBody
	public Map<String,String> calcLeaveTime(Date startTime,Date endTime) throws Exception {
		String goWorkTimeString="08:30:00";
		String midWorkTimeString="12:00:00";
		String endWorkTimeString="18:00:00";
		
		String[] legalHolidays2019= {//2019国家规定的法定节假日
				"2019-01-01", "2019-02-04", "2019-02-05", "2019-02-06", "2019-02-07", 
				"2019-02-08","2019-02-09", "2019-02-10","2019-04-05", "2019-04-06", 
				"2019-04-07", "2019-05-01", "2019-06-07", "2019-06-08", "2019-06-09", 
				"2019-09-13", "2019-09-14", "2019-09-15", "2019-10-01", "2019-10-02", 
				"2019-10-03", "2019-10-04", "2019-10-05", "2019-10-06", "2019-10-07"
		};
		String[] T2019= {//2019国家规定需要调休的班
				"2019-02-02","2019-02-03","2019-09-29","2019-10-12"			
		};
		String[] legalHolidays2020= {//2020国家规定的法定节假日
				"2020-01-01","2020-01-24","2020-01-25","2020-01-26","2020-01-27",
				"2020-01-28","2020-01-29","2020-01-30","2020-04-04","2020-04-05",
				"2020-04-06","2020-05-01","2020-05-02","2020-05-03","2020-05-04",
				"2020-05-05","2020-06-25","2020-06-26","2020-06-27","2020-10-01",
				"2020-10-02","2020-10-03","2020-10-04","2020-10-05","2020-10-06",
				"2020-10-07","2020-10-08"
		};
		String[] T2020= {//2020国家规定需要调休的班
				"2020-01-19","2020-02-01","2020-04-26","2020-05-09","2020-06-28",
				"2020-09-27","2020-10-10"				
		};

		Map<String, String> map=new HashMap<String, String>();
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		String sStartDate= sdf.format(startTime);
		String sEndDate = sdf.format(endTime);
		
		String[] legalHolidays= {};
		String[] tiaoxiudays= {};
		
		System.out.println("传入的请假时间:"+sStartDate+" "+sEndDate);

		List<Date> lstDays=new ArrayList<Date>();
		
		Date startD=sdf.parse(sStartDate);
		Date endD=sdf.parse(sEndDate);
		Date newstartD=null;
		Date newendD=null;
		Date date=startD;
		
		Calendar cal=Calendar.getInstance();
		cal.setTime(startD);
		int i = cal.get(Calendar.DAY_OF_WEEK);
		while (date.equals(endD)||date.before(endD)) {
			int iFiled=cal.get(Calendar.DAY_OF_WEEK);
			String strDateString= sdf.format(date);
		    String strCurrentYear=String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
		    String strDateYear=sdf.format(date).split("-")[0];
			legalHolidays=strDateYear.equals(strCurrentYear)?legalHolidays2019:legalHolidays2020;
			tiaoxiudays=strDateYear.equals(strCurrentYear)?T2019:T2020;
			
			
			if((iFiled==Calendar.SATURDAY||iFiled==Calendar.SUNDAY||
                                    Arrays.asList(legalHolidays).contains(strDateString))
				      &&!Arrays.asList(tiaoxiudays).contains(strDateString)) {
				//这里就是做的周六周末和国家法定节假日的过滤
			}else {
				lstDays.add(date);
			}
			cal.add(Calendar.DATE, 1);
			date=cal.getTime();
		}
		
		SimpleDateFormat sdfTime=new SimpleDateFormat("HH:mm:ss");
		String sStartTime= "";
		String sEndTime = "";
		
		if(lstDays.size()>0) {//除过节假日后的请假天
			newstartD=lstDays.get(0);
			newendD=lstDays.size()==1?newendD=lstDays.get(0):lstDays.get(lstDays.size()-1);

			//新的开始天和原来的开始天是一样的,那就用原来的请假开始时间  否则就用早上上班时间
			sStartTime=newstartD.equals(startD)?sdfTime.format(startTime):goWorkTimeString;
			//新的结束天和原来的结束天是一样的,那就用原来的请假结束时间  否则就用下午下班时间
			sEndTime=newendD.equals(endD)?sdfTime.format(endTime):endWorkTimeString;

		}else {
			System.out.println("请假时间属于国家法定假节日或周六周末,不计算");
			map.put("leaveDays", "0");
			return map;
		}		
	
		Boolean sameDayBoolean=newstartD.equals(newendD);//判断是否是同一天
		Double leaveDays=0.0;
		if(sameDayBoolean) {//同一天的情况	
			System.out.println("同一天计算方式");
			Integer startInteger= Integer.parseInt(sStartTime.split(":")[0]);
			Integer endInteger= Integer.parseInt(sEndTime.split(":")[0]);
			
			String resultString=String.valueOf(endInteger-startInteger);
			switch (resultString) {
				case "4":
				case "6":
					leaveDays+=0.5;
					break;
				case "10":
					leaveDays+=1;
					break;
				default:
					break;
			}
		}else {//不同一天
			Date sStDate=newstartD;
			Calendar clCalendar=Calendar.getInstance();
			clCalendar.setTime(sStDate);
			clCalendar.add(Calendar.DATE, 1);
			Date newStDate=clCalendar.getTime();
			if(newStDate.equals(newendD)) {//相邻天的情况
				System.out.println("相邻天无间隔计算方式");
				Integer startInteger= Integer.parseInt(sStartTime.split(":")[0]);
				Integer endInteger= Integer.parseInt(sEndTime.split(":")[0]);
					
				String resultString=String.valueOf(endInteger-startInteger);
					switch (resultString) {
					case "0":
						leaveDays+=1;
						break;
					case "4":
					case "6":
						leaveDays+=1.5;
						break;
					case "10":
						leaveDays+=2;
						break;
					default:
						break;
					}
					
			}else {//中间有跨天情况
				System.out.println("有间隔计算方式");
				for (int j = 1; j < lstDays.size()-1; j++) {
					leaveDays+=1;
				}
				Integer startInteger= Integer.parseInt(sStartTime.split(":")[0]);
			
				switch (startInteger.toString()) {
					case "8":
						leaveDays+=1;
						break;
					case "12":
						leaveDays+=0.5;
						break;
					case "18":
						leaveDays+=0;
						break;
					default:
						break;
				}
				Integer endInteger= Integer.parseInt(sEndTime.split(":")[0]);
				switch (endInteger.toString()) {
					case "8":
						leaveDays+=0;
						break;
					case "12":
						leaveDays+=0.5;
						break;
					case "18":
						leaveDays+=1;
						break;
					default:
						break;
				}
			}
		}
		map.put("leaveDays", leaveDays.toString());
		return map;
	}