Java 排除法定节假日、周六日以及工作日午休,计算两个Date相差的时间

系统考勤请假中的方法:

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 >
        select time from wx_kq_qingjia_maintain where del_flag = 0 and time_type = 2
    </select>

    <select >
        select time from wx_kq_qingjia_maintain where del_flag = 0 and time_type = 1
    </select>
<!-- 配置表中查询的工作时间 --> <select > 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