200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Java 计算一段时间段内除去周六日 节假日的工作日数———超详细(全)

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

时间:2022-01-28 05:21:57

相关推荐

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

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

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

实现功能提要:本文章记录的是某段时间的起止时间段内的工作日,既是除去周六周日以及节假日日期的工作日数;

注释比较多,因为怕自己忘记,写的可能比较啰嗦~;

1、前端界面简介

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

2、后台处理代码

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

代码部分:

package .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 .oa.leave.entity.OaAttendanceVacation; // 假期信息实体类import .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 (pareTo(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》

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。