系統考勤請假中的方法:
1、在選中時間區間后,排除掉法定的節假日、正常雙休和午休的兩個小時,同時將調休日算作正常工作時間。
2、最后返回的天數是double類型的,是半天或是整天。
代碼部分:
1、從頁面拿到開始時間和結束時間(頁面用的是vue.js),當前是String類型
/** * 計算請假天數 */ @Login @RequestMapping("/calculationTime") public R calculationTime(@RequestParam Map<String, Object> params){ DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); double dayTime = 0; dayTime = wxUserHolidayService.calculationTime(String.valueOf(params.get("stime")), String.valueOf(params.get("etime"))); double days = wxUserHolidayService.halfDayMath(dayTime); return R.ok().put("days",days); }
2、需要的具體方法,根據需要進行取舍
package com.hnzie.modules.kaoqin.service; import com.baomidou.mybatisplus.service.IService; import com.hnzie.modules.kaoqin.entity.WxUserHolidayEntity; import java.util.*; public interface WxUserHolidayService extends IService<WxUserHolidayEntity> {
// 獲取假期日期 String[] holiday1(); // 獲取調休工作日期 String[] holiday2(); // 獲取除午休的工作時間 String[] workTimes(); /** * 計算請假天數,去除周末、節假日 * @param stime * @param etime */ double calculationTime(String stime, String etime); /** * 去重 * @param str */ List<String> removal(List<String> str); /** * 獲取兩個日期之間的所有日期,去掉周末 * @param startDate * @param endDate * @return */ List<String> getDates(String startDate, String endDate); /** * 字符串轉時間 * @param dateStr * @param index * @return */ Date StringToDate(String dateStr, int index); /** * 時間轉字符串 * @param date * @param index * @return */ String dateToString(Date date, int index); /** * 獲取法定節假日或者調休 * @param num * @return */ List<String> holiday(int num); /** * 獲取不同部門工作時間 * @return */ String[] workTime(); // 計算整天或半天 double halfDayMath(double time);
}
3、實現方法
package com.hnzie.modules.kaoqin.service.impl; import com.baomidou.mybatisplus.service.impl.ServiceImpl; import com.hnzie.modules.kaoqin.dao.WxUserHolidayDao; import com.hnzie.modules.kaoqin.entity.WxUserHolidayEntity; import com.hnzie.modules.kaoqin.service.WxQingjiaMaintainService; import com.hnzie.modules.kaoqin.service.WxUserHolidayService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; @Service("wxUserHolidayService") @Slf4j public class WxUserHolidayServiceImpl extends ServiceImpl<WxUserHolidayDao, WxUserHolidayEntity> implements WxUserHolidayService {
/** * 定義常見的時間格式 */ private static String[] dateFormat = { "yyyy-MM-dd HH:mm:ss", // 0 "yyyy/MM/dd HH:mm:ss", // 1 "yyyy年MM月dd日HH時mm分ss秒", // 2 "yyyy-MM-dd", // 3 "yyyy/MM/dd", // 4 "yy-MM-dd", // 5 "yy/MM/dd", // 6 "yyyy年MM月dd日", // 7 "HH:mm:ss", // 8 "yyyyMMddHHmmss", // 9 "yyyyMMdd", // 10 "yyyy.MM.dd", // 11 "yy.MM.dd", // 12 "MM月dd日HH時mm分", // 13 "yyyy年MM月dd日 HH:mm:ss", // 14 "yyyy-MM-dd HH:mm", // 15 "yyMMdd" // 16 }; @Override public String[] holiday1() { return baseMapper.selectLawHolidayDate(); } @Override public String[] holiday2() { return baseMapper.selectLawWorkDate(); } @Override public String[] workTimes() {
String S = baseMapper.selectTimeTable(Const.timeTableKey);
Map<String,Object> parse = (Map<String,Object>)JSON.parse(S);
String[] times = new String[4];
times[0] = String.valueOf(parse.get("SstartTime"));
times[1] = String.valueOf(parse.get("SendTime"));
times[2] = String.valueOf(parse.get("XstartTime"));
times[3] = String.valueOf(parse.get("XendTime"));
return times; } @Override public double calculationTime(String startTime, String endTime) { // 獲取startTime和endTime之間的所有日期,去掉周六周日 List<String> list = this.getDates(startTime, endTime); // 獲取法定節假日 List<String> fdList = this.holiday(1); // 獲取調休 List<String> txList = this.holiday(2); // 上班時間 String[] workTime = this.workTime(); String[] split = workTime[2].split(":"); String[] split1 = workTime[1].split(":"); //午休時間 int wxTime = (Integer.valueOf(split[0]) - Integer.valueOf(split1[0])) * 60; // 刪除時間區間中的所有法定節假日 list.removeAll(fdList); DateFormat df = new SimpleDateFormat(dateFormat[3]); String st =startTime.substring(0, 10); String en =endTime.substring(0, 10); try { Date sts =df.parse(startTime.substring(0, 10)); Date ens =df.parse(endTime.substring(0, 10)); for (String s : txList) { Date ss =df.parse(s); if ((ss.before(ens) && ss.after(sts)) || ss.equals(sts) || ss.equals(ens)) { // 添加時間區間中的所有調休日期 list.add(s); } } }catch (Exception e){ e.printStackTrace(); } // 去重 list = this.removal(list); // 開始當天上午上班時間、上午下班時間、下午上班時間、下午下班時間 String amWorkYes = startTime.substring(0, 11) + workTime[0]; String amWorkNo = startTime.substring(0, 11) + workTime[1]; String pmWorkYes = startTime.substring(0, 11) + workTime[2]; String pmWorkNo = startTime.substring(0, 11) + workTime[3]; // 結束當天上午上班時間、上午下班時間、下午上班時間、下午下班時間 String amWorkYesEnd = endTime.substring(0, 11) + workTime[0]; String amWorkNoEnd = endTime.substring(0, 11) + workTime[1]; String pmWorkYesEnd = endTime.substring(0, 11) + workTime[2]; String pmWorkNoEnd = endTime.substring(0, 11) + workTime[3]; double time = 0; if (list.size() == 0) { // 申請日期是法定節假日 return time; } else if (list.size() == 1) { // 請假一天 if (startTime.compareTo(pmWorkNo) > 0) { return time; } if (endTime.compareTo(amWorkYes) < 0) { return time; } if (startTime.compareTo(amWorkNo) >= 0 && endTime.compareTo(pmWorkYes) <= 0) { return time; } // 開始時間小於上午上班時間,開始時間等於上午上班時間 if (startTime.compareTo(amWorkYes) < 0) { startTime = amWorkYes; } // 結束時間大於下午下班時間,結束時間等於下午下班時間 if (endTime.compareTo(pmWorkNo) > 0) { endTime = pmWorkNo; } // 開始時間大於上午下班時間,小於下午上班時間,開始時間等於下午上班時間 if (startTime.compareTo(amWorkNo) >= 0 && startTime.compareTo(pmWorkYes) <= 0) { startTime = pmWorkYes; } // 結束時間大於上午下班時間,小於下午上班時間,結束時間等於上午下班時間 if (endTime.compareTo(amWorkNo) >= 0 && endTime.compareTo(pmWorkYes) <= 0) { endTime = amWorkNo; } Date start = this.StringToDate(startTime, 15); // 0或者15 Date end = this.StringToDate(endTime, 15); // 三種情況,1:請假時間全在上午,2:請假時間全在下午,3:包含午休時間 if (startTime.compareTo(amWorkYes) >= 0 && endTime.compareTo(amWorkNo) <= 0) { double minute = (end.getTime() - start.getTime()) / (1000 * 60); time = minute / (8 * 60); } else if (startTime.compareTo(pmWorkYes) >= 0 && endTime.compareTo(pmWorkNo) <= 0) { double minute = (end.getTime() - start.getTime()) / (1000 * 60); time = minute / (8 * 60); } else if (startTime.compareTo(amWorkNo) < 0 && endTime.compareTo(pmWorkYes) > 0) { double minute = (end.getTime() - start.getTime()) / (1000 * 60) - wxTime; time = minute / (8 * 60); } return time; } else { // 處理請假多天的情況 // 申請開始時間處理 if (list.contains(st)) { if (startTime.compareTo(amWorkYes) < 0) { startTime = amWorkYes; } if (startTime.compareTo(pmWorkNo) > 0) { startTime = pmWorkNo; } if (startTime.compareTo(amWorkNo) >= 0 && startTime.compareTo(pmWorkYes) <= 0) { startTime = pmWorkYes; } Date start = this.StringToDate(startTime, 15); // 0或者15 Date end = this.StringToDate(pmWorkNo, 15); if (startTime.compareTo(amWorkNo) < 0) { // 減去中午一小時 double t = (end.getTime() - start.getTime()) / (1000 * 60) - wxTime; time = time + t / (8 * 60); } else { double t = (end.getTime() - start.getTime()) / (1000 * 60); time = time + t / (8 * 60); } list.remove(st); } // 申請結束時間處理 if (list.contains(en)) { if (endTime.compareTo(amWorkYesEnd) < 0) { endTime = amWorkYesEnd; } if (endTime.compareTo(pmWorkNoEnd) > 0) { endTime = pmWorkNoEnd; } if (endTime.compareTo(amWorkNoEnd) >= 0 && endTime.compareTo(pmWorkYesEnd) <= 0) { endTime = amWorkNoEnd; } Date end = this.StringToDate(endTime, 15);// 0或者15 Date start = this.StringToDate(amWorkYesEnd, 15); if (endTime.compareTo(pmWorkYesEnd) > 0) { double t = (end.getTime() - start.getTime()) / (1000 * 60) - wxTime; time = time + t / (8 * 60); } else { double t = (end.getTime() - start.getTime()) / (1000 * 60); time = time + t / (8 * 60); } list.remove(en); } // 天數計算集合中剩下的個數就可以 time = time + list.size(); return time; } } /** * 去重 * @param str */ @Override public List<String> removal(List<String> str) { Set<String> s = new HashSet<String>(str); str.clear(); str.addAll(s); return str; } /** * 獲取兩個日期之間的所有日期,去掉周末 * @param startDate * @param endDate */ @Override public List<String> getDates(String startDate, String endDate) { List<String> result = new ArrayList<String>(); Calendar startDay = Calendar.getInstance(); Calendar endDay = Calendar.getInstance(); startDay.setTime(StringToDate(startDate, 3)); endDay.setTime(StringToDate(endDate, 3)); while (startDay.before(endDay)) { int week = startDay.get(Calendar.DAY_OF_WEEK); if (7 != week && 1 != week) { result.add(dateToString(startDay.getTime(), 3)); } startDay.add(Calendar.DAY_OF_YEAR, 1); } // 驗證結束日期是否是周六周日 int week = endDay.get(Calendar.DAY_OF_WEEK); if (7 != week && 1 != week) { result.add(dateToString(endDay.getTime(), 3)); } return result; } /** * 字符串轉時間 * @param dateStr * @param index */ @Override public Date StringToDate(String dateStr, int index) { DateFormat df = null; try { df = new SimpleDateFormat(dateFormat[index]); return df.parse(dateStr); } catch (Exception aioe) { return null; } } /** * 時間轉字符串 * @param date * @param index */ @Override public String dateToString(Date date, int index) { if (date == null) { return null; } return new SimpleDateFormat(dateFormat[index]).format(date); } /** * 獲取法定節假日或者調休 * @param num */ @Override public List<String> holiday(int num) { if (num == 2) { return Arrays.asList(this.holiday2()); } else { return Arrays.asList(this.holiday1()); } } /** * 獲取不同部門工作時間 */ @Override public String[] workTime() { return this.workTimes(); } @Override public double halfDayMath(double time){ String timeStr = time+""; System.out.println("timeStr = [" + timeStr + "]"); String[] timeArr = timeStr.split("\\."); int t1 = Integer.valueOf(timeArr[0]); System.out.println("t1 = [" + t1 + "]"); int t2 = Integer.valueOf(timeArr[1].substring(0, 1)); System.out.println("t2 = [" + t2 + "]"); if (t2 < 5){ return t1; }else if (t2>5){ t1++; return t1; }else { return t1+0.5f; } } }
4、dao層的方法
package com.hnzie.modules.kaoqin.dao; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.hnzie.modules.kaoqin.entity.WxUserHolidayEntity; import org.apache.ibatis.annotations.Param; public interface WxUserHolidayDao extends BaseMapper<WxUserHolidayEntity> { //查詢所有節假日 String[] selectLawHolidayDate(); //查詢所有調休(上班)日 String[] selectLawWorkDate(); String selectTimeTable(@Param("key") String key); }
5、mapper中sql語句
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.hnzie.modules.kaoqin.dao.WxUserHolidayDao"> <select id="selectLawHolidayDate" resultType="String"> select time from wx_kq_qingjia_maintain where del_flag = 0 and time_type = 2 </select> <select id="selectLawWorkDate" resultType="String"> select time from wx_kq_qingjia_maintain where del_flag = 0 and time_type = 1 </select>
<!-- 配置表中查詢的工作時間 --> <select id="selectTimeTable" resultType="String"> select param_value as paramValue from sys_config where status = 1 and param_key = #{key} </select> </mapper>
節假日和調休日需要讀取放在數據庫中的數據
只排除節假日和周六日的https://blog.csdn.net/wujian_csdn_csdn/article/details/86480234