业务:
公出申请流程需要根据员工的班次以及实际填写的公出出厂时间以及公出归厂时间,计算出公出时长
班次:班次根据配置不同可以分为两笔卡、四笔卡的班次
两笔卡:
C015:P10:8:00[上班卡]|P20:17:00[下班卡]
四笔卡:
C005:P10:8:00[上午上班卡]|P20:12:00[上午下班卡]|P10:13:00[下午上班卡]|P20:17:00[下午下班卡]
案例:员工A的上班时间班次:上午8点到12点,下午13点到17点 中间休息1小时
公出申请场景一:2022-06-01 8点到17点(计算公出时长为1天)
公出申请场景二:2022-06-01 8点到 2022-06-02 17点(计算公出时长为2天)
公出申请场景三:2022-06-01 8点到 2022-06-02 12点(计算公出时长为1天4小时)
公出申请场景四:2022-06-01 8点到 2022-06-02 13点(计算公出时长为1天4小时)(需要排除中间1小时的时间,其实跟场景三是一样的计算方式)
公出时长计算方式
ZBC表示员工的对应班次编号(例如:C015)
RLMK_GCSJ_WORK_TIME_ZBC 表示指定维护的两笔卡记录信息
RLMK_GCSJ_WORK_TIME 表示默认班次
public Long getGCWorkTime(String gh,String start,String end) throws ParseException {
String start_date=DateUtil.formatDateString(start);//start.split(" ")[0];
String start_time=DateUtil.formatTime(DateUtil.parseToDate(start));//start.split(" ")[1];
String end_date=DateUtil.formatDateString(end);//end.split(" ")[0];
String end_time=DateUtil.formatTime(DateUtil.parseToDate(end));//end.split(" ")[1];
List<Date> dateList = new ArrayList<Date>();
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
String zbc = DBUtil.getValuefromDB("ZBC","select ZBC from BO_JACK_RLMK_RYXX_M WHERE GH ='"+gh+"'");
//格式 CODE[数值1-数值2] 案例: C017[14400-14400] C018[14400-14400]
//CODE BPM->人力资源->考勤参数视图->科室工作时间->代码
//数值1 表示两笔班次 第一笔卡 增加毫秒数,数值2 表示两笔班次 第二笔卡 减少毫秒数
String zbc_name = ConstantDao.getInstance().getCanstantValueByName("RLMK_GCSJ_WORK_TIME_ZBC", "C017 C018");
int firstTime_s = 60 * 60 * 4,secondTime_s = -60 * 60 * 4;
if(!StringUtils.isEmpty(zbc) && zbc_name.contains(zbc)){
String[] zbc_name_new = zbc_name.split(" ");
for (String s : zbc_name_new) {
if(s.contains(zbc) && s.contains("[")){
firstTime_s = Integer.valueOf(s.substring(s.indexOf("[")+1,s.indexOf("-")));
secondTime_s = -Integer.valueOf(s.substring(s.indexOf("-")+1,s.indexOf("]")));
break;
}
}
}
/*Boolean zbc_flag = false;//判断 人员班次是不是两笔卡打卡班次
if(!StringUtils.isEmpty(zbc) && !zbc_name.contains(zbc)){
zbc_flag = true;
}*/
String name = DBUtil.getValuefromDB("name","select k.name from BO_JACK_RLMK_RYXX_M m LEFT JOIN BO_JACK_RLMK_KQCS_M k on m.ZBC=k.CODE WHERE GH='"+gh+"' and k.type='科室工作时间'");
String namenew = null;
if(StringUtils.isNotEmpty(name)){
namenew = name.replace("P10:","").replace("P20:","");
}else{//默认班次
namenew = ConstantDao.getInstance().getCanstantValueByName("RLMK_GCSJ_WORK_TIME", "08:00|12:00|13:00|17:00");
}
String times[] = namenew.split("\\|");
for (int i = 0; i < times.length; i++) {
if(times[i].contains("[")){
dateList.add(timeFormat.parse(times[i].substring(0,times[i].indexOf("["))+":00"));
}else{
dateList.add(timeFormat.parse(times[i]+":00"));
}
}
//判断 两笔卡逻辑:由于一天上班8小时,所以按照第一笔增加4小时,第二笔卡退后4小时计算
if (times.length == 2 ){
//获取中午休息时间 开始时间
String firstTime = DateUtil.addSecondStr(timeFormat.format(dateList.get(0)), firstTime_s);
//获取中午休息时间 结束时间
String secondTime = DateUtil.addSecondStr(timeFormat.format(dateList.get(1)), secondTime_s);
dateList.add(timeFormat.parse(firstTime));
dateList.add(timeFormat.parse(secondTime));
//排序 正序
Collections.sort(dateList);
}
Date start_time_d=timeFormat.parse(start_time),end_time_d=timeFormat.parse(end_time);
Long start_time_t=start_time_d.getTime(),end_time_t=end_time_d.getTime();
if(start_time_t <= dateList.get(0).getTime()){
start_time_t = dateList.get(0).getTime();
}
if(end_time_t >= dateList.get(3).getTime()){
end_time_t = dateList.get(3).getTime();
}
if(start_date.equals(end_date)){//同天
//计算 小时数
//如果时间包含中午休息时间去除
if(start_time_t <= dateList.get(1).getTime() && end_time_t >= dateList.get(2).getTime()){
return end_time_t-start_time_t-(dateList.get(2).getTime()-dateList.get(1).getTime());
//请勿删除 保留有用 2020年03月25日 14点05分 13526 计算 开始时间 结束时间 其中一个在中午休息时间之间
/* }else if(start_time_t > dateList.get(1).getTime() && end_time_t >= dateList.get(2).getTime()){
return end_time_t-dateList.get(2).getTime();
}else if(start_time_t <= dateList.get(1).getTime() && end_time_t < dateList.get(2).getTime()){
return dateList.get(1).getTime()-start_time_t;*/
}else{
return end_time_t-start_time_t;
}
}else{//不同天
//获取天数集合
List<String> rq = DateUtil.getDateList(start_date,end_date);
//获取去除第一天和最后一天剩下的天数
int day = 0;
if(rq.size()>=3){
day = rq.size()-2;
}
Long day_time_l = day * 8 * 60 * 60 * 1000L,start_time_l = 0L,end_time_l = 0L;
if(start_time_t <= dateList.get(1).getTime()){
start_time_l=dateList.get(3).getTime()-(dateList.get(2).getTime()-dateList.get(1).getTime())-start_time_t;
}else{
start_time_l=dateList.get(3).getTime()-start_time_t;
}
if(end_time_t >= dateList.get(2).getTime()){
end_time_l=end_time_t-(dateList.get(2).getTime()-dateList.get(1).getTime())-dateList.get(0).getTime();
}else{
end_time_l=end_time_t-dateList.get(0).getTime();
}
return day_time_l+start_time_l+end_time_l;
}
}
public static List<String> getDateList(String beginDate,String endDate) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(beginDate));
List<String> list = new ArrayList<String>();
for (long d = cal.getTimeInMillis(); d <= sdf.parse(endDate).getTime(); d = get_D_Plaus_1(cal)) {
list.add(sdf.format(d));
}
return list;
}