Java 计算一段时间段内除去周六日、节假日的工作日数‘’

  • 1、前端界面简介
  • 2、后台处理代码
  • 3、注:
    • 《END》

实现功能提要: 本文章记录的是某段时间的起止时间段内的工作日,既是除去周六周日以及节假日日期的工作日数;
注释比较多,因为怕自己忘记,写的可能比较啰嗦~;


1、前端界面简介

其他的先不考虑,主要是由前台传递到后台的假期开始时间和结束时间;


2、后台处理代码

此段直接进入正题,处理代码我封装到Utils工具类中了,因此关于接收前台时间数据、方法的调用以及参数的传递就不在细说,只提一点就是:传到工具类中的参数有三个,分别是假期开始、假期结束时间以及假期信息表的service对象~

代码部分:

package cn.com.ikdo.oa.leave.utils;
/*** @Descript: 工作日计算*/
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;import cn.com.oa.leave.entity.OaAttendanceVacation; // 假期信息实体类
import cn.com.oa.leave.service.OaAttendanceVacationService; // 假期信息表的service对象public class DutyDaysUtils {@SuppressWarnings("deprecation")public static float getDutyDays(Date startDate, Date endDate, OaAttendanceVacationService oaAttendanceService) {/* 此处 result 的返回值及其类型是因为数据库中与之相关的数据是float类型的,因此设置成这样,有需要的童鞋可以根据个人情况而定————设置成这样的目的是为了能存储带小数点的数字*/Float result = 0F;/*此处一定要new两个时间对象进行接收传递来的参数,否则会在之后保存请假的起止日期时发现用户选择的起止日期和数据库中的日期不一致,原因就在于下面的代码会操作开始日期并使其发生改变,而结束日期不会变化,但是还是都统一处理一下的好(强迫症~)*/Date startDates = new Date(startDate.getTime());Date endDates = new Date(endDate.getTime());/* 此段主要是为了达到半天请假记录的处理,比如我是6月11日上午11点开始请假,那么就相当于我是早上请假,请假的第一天就会记为一个工作日,如果我是12点之后假期开始,那么就是半个工作日(如果想细分就需要自己在琢磨琢磨了),结束日期与之类似,但是需要注意的是,结束日期12点之前算是半个工作日,12点之后算是一个工作日,豫开始日期的正好相反*/SimpleDateFormat spf = new SimpleDateFormat("HH");String start = spf.format(startDates);String end = spf.format(endDates);int s = Integer.parseInt(start);int e = Integer.parseInt(end);// 开始时间大于12点的按半天算,小于12的按一天算if (s <= 12) {result = result + 1F;} else {result = result + 0.5F;}// 结束时间大于12点的按一天算,小于12的按半天算if (e <= 12) {result = result + 0.5F;} else {result = result + 1F;}/*重点问题:下面的此段代码是为了将date类型的yyyy-MM-dd HH:mm:ss格式转为 yyyy-MM-dd,实际是转化成yyyy-MM-dd 00:00:00转化的原因:时分秒参与while循环会产生bug:当起始时间的时分秒大于结束时间的时分秒时,一旦起止时间的年月日相等就会导致while循环结束,产生少计算一次的问题;转化方法:通过处理将参与while循环的起止时间格式为年月日类型的:先通过date转为string类型的yyyy-MM-dd格式,再转成date类型的即可(转化方法想过使用更简便的,但是很无奈没找到,只能这么处理了,有更简便的童鞋可以告知一声~)*/DateFormat df = new SimpleDateFormat("yyyy-MM-dd");String dfStart = df.format(startDates);String dfEnd = df.format(endDates);SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");try {Date startparam = formatter.parse(dfStart);Date endparam = formatter.parse(dfEnd);// 每次循环的都查看计算日期是否超出结束日期while (startparam.compareTo(endparam) <= 0) {// 参与判断日期的星期码不等于周六且不等于周日的星期码if (startparam.getDay() != 6 && startparam.getDay() != 0) {// 此处需要注意,本人使用的去除节假日日期的方法是先将节假日的信息(主要//是节日假期起止时间)放入到数据库中,然后通过循环比对参与判断的日期是否在某个节日假期时间内;// 创建一个查询条件对象(没有此方法的可以自己手动将查询条件传递给SQL)LambdaQueryWrapper<OaAttendanceVacation> query = Wrappers.lambdaQuery();// 参与判断的日期大于等于节日假期的开始时间条件(OaAttendanceVacation为假期的实体对象,StartDay是假期开始时间)query.le(OaAttendanceVacation::getStartDay, startparam);// 参与判断的日期小于等于节日假期的开始时间条件(EndDay是假期截止时间)query.ge(OaAttendanceVacation::getEndDay, startparam);// 通过count方法查询是否存在符合条件的int count = oaAttendanceService.count(query);//     若是count仍为0,则说明没有符合条件的,进一步说就是参与判断的日期不是节假日if (count == 0) {// 工作日计数参数加一result++;}}// 此天判断玩完了,对当前日期进行加一操作,使其变成下一天的日期参与下一轮判断startparam.setDate(startparam.getDate() + 1);}} catch (ParseException e1) {e1.printStackTrace();}/*到这里,只能说该统计的都统计了,但是还是有很多问题的,比如说:1、若是请假信息中起止时间为同一天的话就会出现多算的问题;2、若是请假信息中的开始、结束时间有为节假日的,也会出现多算的问题;3、若是请假信息中的起止时间有为周六日的,也会出现多算的问题;因此,下面就需要对请假信息中的起止时间进行梳理判断,判断起止时间是否是在同一天,并在是和否情况下再次判断起止时间是否为节假日;*/// 判断起止时间是否为同一天int isEq = 0;// 创建接收yyyy-MM-dd格式的date类型的起止时间对象,下面会用到Date paramS = new Date();Date paramE = new Date();try {// 经转化成yyyy-MM-dd格式的Date数据(注意,dfStart,dfStart是在上面处理成string类型的起止时间)Date startparam = formatter.parse(dfStart);Date endparam = formatter.parse(dfStart);// 直接比较起止时间是否相等if (startparam.equals(endparam)) {// 是同一天则改变isEq值isEq++;}// yyyy-MM-dd格式的date类型的起止时间数据放入相应对象用于下边的使用paramS = startparam;paramE = endparam;} catch (ParseException e1) {e1.printStackTrace();}if (isEq == 0) {// 起止时间不在同一天的情况下// 开始时间是否在节日假期范围内(OaAttendanceVacation、getStartDay、getEndDay均不在赘述,意思与上面一样)LambdaQueryWrapper<OaAttendanceVacation> queryStart = Wrappers.lambdaQuery();queryStart.ge(OaAttendanceVacation::getStartDay, paramS);queryStart.le(OaAttendanceVacation::getEndDay, paramS);int countStart = oaAttendanceService.count(queryStart);// 结束时间是否在节日假期范围内LambdaQueryWrapper<OaAttendanceVacation> queryEnd = Wrappers.lambdaQuery();queryEnd.ge(OaAttendanceVacation::getStartDay, paramE);queryEnd.le(OaAttendanceVacation::getEndDay, paramE);int countEnd = oaAttendanceService.count(queryEnd);// 判断开始时间不是周六日或节假日if (startDates.getDay() != 6 && startDates.getDay() != 0 && countStart == 0) {result = result - 1F;} else {// 开始时间在周六日或节假日if (s < 12) {result = result - 1F;} else {result = result - 0.5F;}}// 结束时间不是周六日或节假日if (endDates.getDay() != 6 && endDates.getDay() != 0 && countEnd == 0) {result = result - 1F;} else {// 结束时间在周六日或节假日if (e < 12) {result = result - 0.5F;} else {result = result - 1F;}}} else {// 起止时间在同一天的情况下// 开始时间是否处于假期内,只需要查询开始时间或者结束时间即可LambdaQueryWrapper<OaAttendanceVacation> queryStart = Wrappers.lambdaQuery();queryStart.ge(OaAttendanceVacation::getStartDay, paramS);queryStart.le(OaAttendanceVacation::getEndDay, paramS);int countStart = oaAttendanceService.count(queryStart);// 此天非节假日、周六日if (startDates.getDay() != 6 && startDates.getDay() != 0 && countStart == 0) {if (s < 12 && e < 12) {result = result - 2F;}if (s < 12 && e > 12) {result = result - 2F;}if (s > 12 && e > 12) {result = result - 2F;}} else {// 此天为节假日、周六日if (s < 12 && e < 12) {result = result - 1.5F;}if (s < 12 && e > 12) {result = result - 2F;}if (s > 12 && e > 12) {result = result - 1.5F;}}}return result;}
}

3、注:

  • 星期码:从星期一到星期日的星期码是1,2,3,4,5,6,0。其实就是星期几对应的类似于索引的一个数码(星期码这个名词是我自己想的,因为觉得挺贴切的。。。还有就是不知道它真叫什么~)
  • getDay()方法就是获得这一天的星期码(int类型的),其功能就是用于获取传入日期的星期码的;
  • getDay()方法已经不被官方继续支持使用了,从 JDK 1.1 开始,由 Calendar.get(Calendar.DAY_OF_WEEK) 取代,但是暂时还能用,有兴趣的可以换成Calendar试试;
  • 另外,里面有几段代码使用频率比较高,有兴趣的可以封装成方法直接调用;

pass:

  • 代码中主要是自己的思路,可能有点啰嗦,就是怕自己以后再看费劲,想着这会麻烦点,以后轻松点~

感悟:

  • 不要对不会的代码心里排斥,多看别人的代码,勇于面对自己的弱点、问题,只有这样才能让自己进步!

《END》

Java 计算一段时间段内除去周六日、节假日的工作日数———超详细(全)相关推荐

  1. java 算出下一个工作日_Java 计算一段时间段内除去周六日、节假日的工作日数———超详细(全)...

    Java 计算一段时间段内除去周六日.节假日的工作日数'' 实现功能提要: 本文章记录的是某段时间的起止时间段内的工作日,既是除去周六周日以及节假日日期的工作日数: 注释比较多,因为怕自己忘记,写的可 ...

  2. Java计算两个时间段内的工作日天数

    一般在OA系统中都会遇到计算员工这段时间内的工作天数. 这种有两种方式可以解决:一是调用第三方服务接口进行计算,二是自己在系统中写代码计算. 一的好处就是每年的节假日不用自己去维护直接用两个时间段就可 ...

  3. php 计算时间段内的工作日 与节假日

    计算方法是取开始时间后的第一个星期一,如果结束时间大于等这一天则用第一个星期一至结束时间的时间的间隔取整周数与余数计算工作日与周末,再加上第一个周一前一周的工作日与节假日. /** 计算时间段内的工作 ...

  4. 金和oa:自定义表单函数计算一段时期内的工作日

    今天介绍一下在自定义表单时如何去计算两个日期之间的工作日.这是很常用的一个js函数,比如在加班中,比如在请假中... 1. 计算两个日期之间的工作日,写附加元素页面 <script langua ...

  5. mysql 计算工作日_MySQL函数查找两个日期之间的工作日数

    该解决方案使用与Rodger基本相同的方法,除了生成矩阵的方法要复杂得多.注意:此解决方案的此输出与NETWORKDAYS不兼容. 与Rodger的解决方案一样,这可以计算开始日期(@S)和结束日期( ...

  6. Oracle计算某日期段内排除周六日之后的天数(请假,工作日,日期型)

    因为本人不是主要从事Oracle等大数据操作方向,所以对于SQL语句了解并不专业,本文主要用于记录自己的使用心得,以及为广大网友提供思路,如果不喜欢我的解析和讲解可以直接跳过,拿走你觉得有用的SQL. ...

  7. java计算两个时间段的重合天数

    由于我要计算一个合同在当月的分摊的金额,所以就要知道这个合同的有效期在本月有多少天,这就要进行两个时间段重合天数的计算. 两个时间段四个时间点,相当于时间轴上的两条线段(b代表起点,e代表端点,b&l ...

  8. JavaScript:在一段时间不连续的数据中获取某一段时间段内相同时间间隔的数据

    需求:绘制highchats折线图,绘制某一个时间段内相同时间频率的图像. 如:绘制2020年5月11日-2020年6月11日之前,每隔4小时一次的数据(绘制近一个月内数据) 请求回的数据如下: 难点 ...

  9. JAVA 计算日期属于当月第几周(日期周计算)

    计算日期属于当月第几周(日期周计算) 本文周计算时间方式为:当月第一个周一为第一周 计算 获取月第一个周一.从当月第一天开始找 第一个周一时间与 sourceTime [传入时间对比],sourceT ...

最新文章

  1. Can't connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock‘ (2)解决思路
  2. 我们是移动的韭菜么?似乎程序员去哪里上班,哪里房价就贵起来了?扎心......
  3. Synchronize锁对象
  4. 云炬60s看世界20211116
  5. reactjs render props向组件内部动态传入带内容的标签
  6. Verilog 补码加法溢出判断及处理
  7. android kotlin类内绑定事件,Android kotlin 点击事件防重复
  8. mysql 中文排序_mysql如何按照中文排序解决方案
  9. huffman算法c语言程序,哈夫曼算法构造代码
  10. 微软提高 Microsoft 365 的漏洞奖励
  11. abaqus dat文件 matlab_提升Abaqus求解效率的七种武器
  12. 三、如何设置npm镜像
  13. Android 2.3 版本中链接边框问题解决
  14. ExecutorService中submit和execute、Runnable和Callable
  15. linux中printf命令,总结linux下printf命令的用法
  16. 量子加密欲应用到智能手机 让黑客流泪
  17. android微信红包提醒,微信红包提醒怎么设置 微信红包提醒设置教程
  18. cesium 经纬度绘制点_Cesium搜索经纬度并标点
  19. python 制作抽奖箱_海安当地横幅制作值得推荐,抽奖箱制作-漫谈
  20. 31.SUM() 函数

热门文章

  1. 矩形的面积为什么是长乘以宽
  2. 主成分分析(PCA)与t-SNE
  3. 【思特奇杯·云上蓝桥-算法集训营】第2周作业
  4. 我在CSDN开博啦!
  5. gentoo 出现普通用户 字体全部口口口口口口口口口口口口我解决办法
  6. 荣耀v30鸿蒙5g荣耀有隔空操作吗,荣耀V30没秘密了,隔空操作+麒麟990+后置四摄,要干翻小米?...
  7. plsql因目标主机或对象不存在_原创 | 由勒索软件谈起:重新审视工业信息安全,要从工业主机开始...
  8. 如何删除Word空白页,这四种方法轻松搞定
  9. php mysql 网站 任务书_办公用品网上商城的设计与实现PHP+MYSQL任务书
  10. win7 家庭组连接 使用用户账号和密码连接到其他计算机,Win7 家庭组 共享 要密码用户名 及无权访问 解决方案...