zoukankan      html  css  js  c++  java
  • 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 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

  • 相关阅读:
    java中return在Try-Catch中的执行顺序
    面向对象软件开发方法概述
    内部类
    JAVA中的继承
    错题分析
    【cocos2d-x 手游研发小技巧(1)自定义制作怪物伤害数值】
    【cocos2d-x 手游研发----地图活起来了】
    【cocos2d-x 手游研发----精灵的八面玲珑】
    【cocos2d-x 手游研发----研发思路及感想】
    通俗易懂的讲解区块链
  • 原文地址:https://www.cnblogs.com/BKhp/p/12017808.html
Copyright © 2011-2022 走看看