目录
1.假设上班时间如下:
- 上班时间为:08:30:00
- 中午休息时间为:12:00:00 到13:30:00
- 下班时间:18:00:00
- 每次请假必须至少请假半天(例如:08:30到12:00算0.5天 12:00到18:00算0.5天) 以上
- 支持2019和2020年国家法定节假日,其他年份请自行添加
2.请假时间计算方式:
任选两个时间段(无论是从周末、国家节假日开始请假 到 周末、国家节假日结束请假 都支持)
2.1.去掉周六周末(但是国家调休的有些班是在周六周末 所以要做判断,如果周六或者周末 是国家规定调休的班,那么就不能去掉,否则去掉)
2.2.去掉国家法定节假日
3.请假可能存在的情况:
3.1. 请假日期和结束日期相同(同一天) 例如:2019-12-10 08:30:00 - 2019-12-10 12:00:00
3.2 .请假日期和结束日期相邻(相邻的两天)例如:2019-12-10 08: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;
}