个人笔记 java 根据排班计划得出工作时间(排除节假日,周末,休息方式)

个人笔记,根据业务需求所写
思路:得到查找的时间段(date1)所跨的排班计划(data)
遍历每个排班计划的开始时间与结束时间,以及是否存在节假日(节假日开始时间,结束时间),休息方式(单休,双休,无休)。
数据结构如下:
第一条:date1的开始时间----data(0)的排班结束时间
中间的排班计划:data()的排班开始时间----排班结束时间
最后一条排班计划:data(data.size)排班开始时间-----date1结束时间
拿到数据结构后,每一个时间段与节假日时间段进行比较(存在节假日),算出两者重叠时间,以及周六周日的重叠天数

 /**
       * 计划工作时间/天
       * @param startDate 往前30天
       * @param endDate	今日
       * @param filter
       * @return
       * @throws DatasweepException
       */
      private long getPlanTime(String startDate,String endDate,RunningStatusFilter filter) throws DatasweepException{
    	  String key = null;
    	  String startPlan = null;
    	  String endPlan = null;
    	  String startHoliday = null;
    	  String endHoliday = null;
    	  String weekendPlan = null;

    	  long sumHoliday = 0;//假期天数
    	  long sumDay = 0;
    	  DateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    	  
    	  Map<String, Object> map = new HashMap<String, Object>();
    	  
    	try{
    		Vector<String[]> data = filter.getPlanWorkTime(startDate,endDate);//获取开始时间所处时间段
    		
    		Date d1=sdf.parse(startDate);
    		Date d2=sdf.parse(endDate);
    		sumDay = (d2.getTime()-d1.getTime()+1000000)/(3600*24*1000);//间隔时间天数
    		
    		if(0!=data.size()&&null!=data)
    		{
    			for(int i =0;i<data.size();i++){
    				key = data.get(i)[0];
        			startPlan = data.get(i)[2];//排班开始时间
        			endPlan = data.get(i)[3];//排班结束时间
        			startHoliday = data.get(i)[4];//假期开始时间
        			endHoliday = data.get(i)[5];//假期结束时间
        			weekendPlan = data.get(i)[6];//周末放假计划
        			
        			if("1".equals(weekendPlan)){//周末双休
        					long reapertdays = 0;//重叠天数 
            	    		while(i==0){//第一条日历数据
            	    			long sumDayOfSat = weekend(startDate,endPlan,6);//排班内有几个周6
            	    			long sumDayOfSun = weekend(startDate,endPlan,7);//排班内有几个周7
            	    			if(""!=startHoliday&&null!=startHoliday){//有节假日
                    				Date d3=sdf.parse(startHoliday);
                    	    		Date d4=sdf.parse(endHoliday);
                    	    		sumHoliday = (d4.getTime()-d3.getTime())/(3600*24*1000)+1;//假期天数
                    	    		//时间段:startDate,endPlan,所需要查询的时间 是否与 节假日时间有重叠
                    	    		map=dateUtils(startDate,endPlan,startHoliday,endHoliday);//得出重叠时间
                    	    		reapertdays = (Long) map.get("reapertdays");	
                    	    		if(0!=reapertdays){//有重叠日期
                    	    			long isReapertDay= isReapert(startHoliday,sumHoliday,1);//重叠天数
                    	    			sumDay = sumDay-(sumHoliday+sumDayOfSat+sumDayOfSun-isReapertDay);
                    	    		}else{
                    	    			sumDay = sumDay -sumHoliday-sumDayOfSat-sumDayOfSun;
                    	    		}
            	    			}else{
            	    				//没有节假日
            	    				sumDay =  sumDay -sumDayOfSat-sumDayOfSun;
            	    			}
            	    			break;
            	    		}
            	    		while(i==data.size()-1&&i!=0){//最后一条日历数据
            	    			long sumDayOfSat = weekend(startPlan,endDate,6);//排班内有几个周6
            	    			long sumDayOfSun = weekend(startPlan,endDate,7);//排班内有几个周7
            	    			if(""!=startHoliday&&null!=startHoliday){//有节假日
            	    				Date d3=sdf.parse(startHoliday);
                    	    		Date d4=sdf.parse(endHoliday);
                    	    		sumHoliday = (d4.getTime()-d3.getTime())/(3600*24*1000)+1;//假期天数
                    	    		//时间段startPlan,endDate
                    	    		map=dateUtils(startPlan,endDate,startHoliday,endHoliday);//得出重叠时间
                    	    		reapertdays = (Long) map.get("reapertdays");
                    	    		if(0!=reapertdays){//有重叠日期
                    	    			long isReapertDay= isReapert(startHoliday,sumHoliday,1);//重叠天数
                    	    			sumDay = sumDay-(sumHoliday+sumDayOfSat+sumDayOfSun-isReapertDay);
                    	    		}else{
                    	    			sumDay = sumDay -sumHoliday-sumDayOfSat-sumDayOfSun;
                    	    		}
            	    			}else{
            	    				//没有节假日
            	    				sumDay =  sumDay -sumDayOfSat-sumDayOfSun;
            	    			}
            	    			break;
            	    		}
            	    		while(i!=0&&i!=data.size()-1){//中间段日历数据
            	    			long sumDayOfSat = weekend(startPlan,endPlan,6);//排班内有几个周6
            	    			long sumDayOfSun = weekend(startPlan,endPlan,7);//排班内有几个周7
            	    			if(""!=startHoliday&&null!=startHoliday){//有节假日
            	    				Date d3=sdf.parse(startHoliday);
                    	    		Date d4=sdf.parse(endHoliday);
                    	    		sumHoliday = (d4.getTime()-d3.getTime())/(3600*24*1000)+1;//假期天数
            	    				//时间段 startPlan ,endPlan
                    	    		map=dateUtils(startPlan,endPlan,startHoliday,endHoliday);//得出重叠时间
                    	    		reapertdays = (Long) map.get("reapertdays");
                    	    		if(0!=reapertdays){//有重叠日期
                    	    			long isReapertDay= isReapert(startHoliday,sumHoliday,1);//重叠天数
                    	    			sumDay = sumDay-(sumHoliday+sumDayOfSat+sumDayOfSun-isReapertDay);
                    	    		}else{
                    	    			sumDay = sumDay -sumHoliday-sumDayOfSat-sumDayOfSun;
                    	    		}
            	    			}else{
            	    				//没有节假日
            	    				sumDay =  sumDay -sumDayOfSat-sumDayOfSun;
            	    			}
            	    			break;
            	    		}
    	    		}
    	    		if("2".equals(weekendPlan)){//周日单休
    	    			long reapertdays = 0;//重叠天数 
    	    			while(i==0){//第一条日历数据
    	    				long sumDayOfSat = weekend(startDate,endPlan,6);//排班内有几个周6
    	    				long sumDayOfSun = weekend(startDate,endPlan,7);//排班内有几个周7
        	    			if(""!=startHoliday&&null!=startHoliday){//有节假日
                				Date d3=sdf.parse(startHoliday);
                	    		Date d4=sdf.parse(endHoliday);
                	    		sumHoliday = (d4.getTime()-d3.getTime())/(3600*24*1000)+1;//假期天数
                	    		//时间段:startDate,endPlan,所需要查询的时间 是否与 节假日时间有重叠
                	    		map=dateUtils(startDate,endPlan,startHoliday,endHoliday);//得出重叠时间
                	    		reapertdays = (Long) map.get("reapertdays");
                	    		if(0!=reapertdays){//有重叠日期
                	    			long isReapertDay= isReapert(startHoliday,sumHoliday,2);//重叠天数
                	    			sumDay = sumDay-(sumHoliday+sumDayOfSat+sumDayOfSun-isReapertDay);
                	    		}else{
                	    			sumDay = sumDay -sumHoliday-sumDayOfSat-sumDayOfSun;
                	    		}
        	    			}else{
        	    				//没有节假日
        	    				sumDay =  sumDay -sumDayOfSat-sumDayOfSun;
        	    			}
        	    			break;
        	    		}
    	    			
    	    			while(i==data.size()-1&&i!=0){//最后一条日历数据
    	    				long sumDayOfSat = weekend(startPlan,endDate,6);//排班内有几个周6
    	    				long sumDayOfSun = weekend(startPlan,endDate,7);//排班内有几个周7
        	    			if(""!=startHoliday&&null!=startHoliday){//有节假日
        	    				Date d3=sdf.parse(startHoliday);
                	    		Date d4=sdf.parse(endHoliday);
                	    		sumHoliday = (d4.getTime()-d3.getTime())/(3600*24*1000)+1;//假期天数
                	    		//时间段startPlan,endDate
                	    		map=dateUtils(startPlan,endDate,startHoliday,endHoliday);//得出重叠时间
                	    		reapertdays = (Long) map.get("reapertdays");
                	    		if(0!=reapertdays){//有重叠日期
                	    			long isReapertDay= isReapert(startHoliday,sumHoliday,2);//重叠天数
                	    			sumDay = sumDay-(sumHoliday+sumDayOfSat+sumDayOfSun-isReapertDay);
                	    		}else{
                	    			sumDay = sumDay -sumHoliday-sumDayOfSat-sumDayOfSun;
                	    		}
        	    			}else{
        	    				//没有节假日
        	    				sumDay =  sumDay -sumDayOfSat-sumDayOfSun;
        	    			}
        	    			break;
        	    		}
    	    			while(i!=0&&i!=data.size()-1){//中间段日历数据
    	    				long sumDayOfSat = weekend(startPlan,endPlan,6);//排班内有几个周6
    	    				long sumDayOfSun = weekend(startPlan,endPlan,7);//排班内有几个周7
        	    			if(""!=startHoliday&&null!=startHoliday){//有节假日
        	    				Date d3=sdf.parse(startHoliday);
                	    		Date d4=sdf.parse(endHoliday);
                	    		sumHoliday = (d4.getTime()-d3.getTime())/(3600*24*1000)+1;//假期天数
        	    				//时间段 startPlan ,endPlan
                	    		map=dateUtils(startPlan,endPlan,startHoliday,endHoliday);//得出重叠时间
                	    		reapertdays = (Long) map.get("reapertdays");
                	    		if(0!=reapertdays){//有重叠日期
                	    			long isReapertDay= isReapert(startHoliday,sumHoliday,2);//重叠天数
                	    			sumDay = sumDay-(sumHoliday+sumDayOfSat+sumDayOfSun-isReapertDay);
                	    		}else{
                	    			sumDay = sumDay -sumHoliday-sumDayOfSat-sumDayOfSun;
                	    		}
        	    			}else{
        	    				//没有节假日
        	    				sumDay =  sumDay -sumDayOfSat-sumDayOfSun;
        	    			}
        	    			break;
        	    		}
    	    		}
    	    		if("5".equals(weekendPlan)){//周末无休息
    	    			long reapertdays = 0;//重叠天数 
    	    			while(i==0){//第一条日历数据
    	    				long sumDayOfSat = weekend(startDate,endPlan,6);//排班内有几个周6
    	    				long sumDayOfSun = weekend(startPlan,endPlan,7);//排班内有几个周7
        	    			if(""!=startHoliday&&null!=startHoliday){//有节假日
                				Date d3=sdf.parse(startHoliday);
                	    		Date d4=sdf.parse(endHoliday);
                	    		sumHoliday = (d4.getTime()-d3.getTime())/(3600*24*1000)+1;//假期天数
                	    		//时间段:startDate,endPlan,所需要查询的时间 是否与 节假日时间有重叠
                	    		map=dateUtils(startDate,endPlan,startHoliday,endHoliday);//得出重叠时间
                	    		reapertdays = (Long) map.get("reapertdays");
                	    		if(0!=reapertdays){//有重叠日期
//                	    			isReapert(startHoliday,sumHoliday,5);
                	    			long isReapertDay= isReapert(startHoliday,sumHoliday,5);//重叠天数
                	    			sumDay = sumDay-(sumHoliday+sumDayOfSat+sumDayOfSun-isReapertDay);
                	    		}else{
                	    			sumDay = sumDay -sumHoliday-sumDayOfSat-sumDayOfSun;
                	    		}
        	    			}else{
        	    				//没有节假日
        	    				sumDay =  sumDay -sumDayOfSat-sumDayOfSun;
        	    			}
        	    			break;
        	    		}
    	    			while(i==data.size()-1&&i!=0){//最后一条日历数据
    	    				long sumDayOfSat = weekend(startPlan,endDate,6);//排班内有几个周6
    	    				long sumDayOfSun = weekend(startPlan,endDate,7);//排班内有几个周7
        	    			if(""!=startHoliday&&null!=startHoliday){//有节假日
        	    				Date d3=sdf.parse(startHoliday);
                	    		Date d4=sdf.parse(endHoliday);
                	    		sumHoliday = (d4.getTime()-d3.getTime())/(3600*24*1000)+1;//假期天数
                	    		//时间段startPlan,endDate
                	    		map=dateUtils(startPlan,endDate,startHoliday,endHoliday);//得出重叠时间
                	    		reapertdays = (Long) map.get("reapertdays");
                	    		if(0!=reapertdays){//有重叠日期
//                	    			isReapert(startHoliday,sumHoliday,5);
                	    			long isReapertDay= isReapert(startHoliday,sumHoliday,5);//重叠天数
                	    			sumDay = sumDay-(sumHoliday+sumDayOfSat+sumDayOfSun-isReapertDay);
                	    		}else{
                	    			sumDay = sumDay -sumHoliday-sumDayOfSat-sumDayOfSun;
                	    		}
        	    			}else{
        	    				//没有节假日
        	    				sumDay =  sumDay -sumDayOfSat-sumDayOfSun;
        	    			}
        	    			break;
        	    		}
    	    			while(i!=0&&i!=data.size()-1){//中间段日历数据
    	    				long sumDayOfSat = weekend(startPlan,endPlan,6);//排班内有几个周6
    	    				long sumDayOfSun = weekend(startPlan,endPlan,7);//排班内有几个周7
        	    			if(""!=startHoliday&&null!=startHoliday){//有节假日
        	    				Date d3=sdf.parse(startHoliday);
                	    		Date d4=sdf.parse(endHoliday);
                	    		sumHoliday = (d4.getTime()-d3.getTime())/(3600*24*1000)+1;//假期天数
        	    				//时间段 startPlan ,endPlan
                	    		map=dateUtils(startPlan,endPlan,startHoliday,endHoliday);//得出重叠时间
                	    		reapertdays = (Long) map.get("reapertdays");
                	    		if(0!=reapertdays){//有重叠日期
//                	    			isReapert(startHoliday,sumHoliday,5);
                	    			long isReapertDay= isReapert(startHoliday,sumHoliday,5);//重叠天数
                	    			sumDay = sumDay-(sumHoliday+sumDayOfSat+sumDayOfSun-isReapertDay);
                	    		}else{
                	    			sumDay = sumDay -sumHoliday-sumDayOfSat-sumDayOfSun;
                	    		}
        	    			}else{
        	    				//没有节假日
        	    				sumDay =  sumDay -sumDayOfSat-sumDayOfSun;
        	    			}
        	    			break;
        	    		}
        			}
    			}
    		}
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	return sumDay;
      }
      /**
       * 得出两个时间段重叠的天数
       * @param startPlans 排班开始时间
       * @param endPlans 排班结束时间
       * @param startHoliday	假期开始时间
       * @param endHoliday	假期结束时间
       * @return
       * @throws ParseException 
       */
      private Map<String,Object> dateUtils(String startPlans, String endPlans, String startHoliday, String endHoliday) throws ParseException{
  			Map<String,Object> map = new HashMap<String , Object>();
    	  	long reapertdays = 0;//重叠天数
    	  	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  			// 标准时间
  			Date bt = sdf.parse(startPlans);
  			Date ot = sdf.parse(endPlans);
  			// 目标时间
  			Date st = sdf.parse(startHoliday);
  			Date ed = sdf.parse(endHoliday);
  			
  			long btlong = Math.min(bt.getTime(), ot.getTime());// 开始时间
  			long otlong = Math.max(bt.getTime(), ot.getTime());// 结束时间
  			long stlong = Math.min(st.getTime(), ed.getTime());// 开始时间
  			long edlong = Math.max(st.getTime(), ed.getTime());// 结束时间
  			if ((stlong >= btlong && stlong <= otlong) || (edlong >= btlong && edlong <= otlong)) {
  				// 一定有重叠部分
  				long sblong = stlong >= btlong ? stlong : btlong;
  				long eblong = otlong >= edlong ? edlong : otlong;
  				String sblongs = sdf.format(sblong);
  				String eblongs = sdf.format(eblong);
  				
  				Date d1=sdf.parse(sblongs);
				Date d2=sdf.parse(eblongs);
				
				String ds1 = sdf.format(d1);
				String ds2 = sdf.format(d2);
				reapertdays=((d2.getTime()-d1.getTime())/(3600*24*1000))+1;//重叠天数
				
				map.put("reapertdays", reapertdays);
				map.put("Ds1", ds1);
				map.put("Ds2", ds2);
				return map;
  			}
  			map.put("reapertdays", reapertdays);
  			return map;  
      }
      /**
       * 节假日与周末重叠 天数
       * @param startHoliday 假期开始时间
       * @param holiday 假期天数
       * @param restType 休息方式 1:双休  2:周日单休
       * @return
       * @throws Exception
       */
      private long isReapert(String startHoliday,long holiday,long restType) throws Exception{
    	  long reatpertDay =0;
    	  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    	  int dayForWeek = 0;
    	  if(holiday==1){//假期只有一天,且为双休形式,得出一天假期为星期几
    		  Calendar c = Calendar.getInstance();
    		  c.setTime(format.parse(startHoliday)); 
        	  if(c.get(Calendar.DAY_OF_WEEK) == 1){
        	   dayForWeek = 7;
        	  }else{
        	   dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        	  }
    		  if(restType==1){
            	  if(dayForWeek==6||dayForWeek==7){
            		  reatpertDay = 1;
            	  }
    		  }
    		  if(restType==2){
        		  if(dayForWeek==7){
        			  reatpertDay = 1;
        		  }
        	  }
    	  }else{
    		  Calendar calendar  =  new GregorianCalendar(); 
    		  for(int i=0;i<holiday;i++){
    			  calendar.setTime(format.parse(startHoliday));
    			  calendar.add(calendar.DATE, i);
    			  if(calendar.get(Calendar.DAY_OF_WEEK) == 1){
    	        	   dayForWeek = 7;
    	        	  }else{
    	        	   dayForWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
    	        	  }
    			  if(restType==1){
    				  if(dayForWeek==6||dayForWeek==7){
                		  reatpertDay++;
                	  }
    			  }
    			  if(restType==2){
    				  if(dayForWeek==7){
    					  reatpertDay++;
    				  }
    			  }
    		  }
    	  }
		return reatpertDay;
      }
      
      /**
       * 给定时间段和星期几,计算该时间段内共有多少个给定的星期几
       * @param start 开始时间,格式yyyy-MM-dd
       * @param end 结束时间,格式yyyy-MM-dd
       * @param a 星期几,从星期一到星期天,分别用数字1-7表示
       * @return 星期几统计数
       */
      private long weekend(String start,String end,int a){
          DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
          long sunDay = 0;//计数
          try{
              Calendar startDate = Calendar.getInstance(); //开始时间
              startDate.setTime(format.parse(start));

              Calendar endDate = Calendar.getInstance();//结束时间
              endDate.setTime(format.parse(end));
              
              int SW = startDate.get(Calendar.DAY_OF_WEEK)-1;//开始日期是星期几
              int EW = endDate.get(Calendar.DAY_OF_WEEK)-1;//结束日期是星期几
              
              long diff = endDate.getTimeInMillis()-startDate.getTimeInMillis();   
              long days = diff / (1000 * 60 * 60 * 24);//给定时间段内一共有多少天
              long w = Math.round(Math.ceil(((days+SW+(7-EW))/7.0)));//给定时间内,共有多少个星期
              sunDay = w;//总的星期几统计数
              if(a<SW)//给定的星期几小于起始日期的星期几,需要减少一天
                  sunDay--;
              if(a>EW)//给定的星期几大于结束日期的星期几,需要减少一天
                  sunDay--;
          }catch(Exception se){
              se.printStackTrace();
          }
          return sunDay;
      } 
}

猜你喜欢

转载自blog.csdn.net/qq_34279442/article/details/83023936