个人笔记,根据业务需求所写
思路:得到查找的时间段(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;
}
}