第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > java 算出下一个工作日_Java 计算一段时间段内除去周六日 节假日的工作日数———

java 算出下一个工作日_Java 计算一段时间段内除去周六日 节假日的工作日数———

时间:2019-03-01 09:03:22

相关推荐

java 算出下一个工作日_Java 计算一段时间段内除去周六日 节假日的工作日数———

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

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

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

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 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 queryStart = Wrappers.lambdaQuery();

queryStart.ge(OaAttendanceVacation::getStartDay, paramS);

queryStart.le(OaAttendanceVacation::getEndDay, paramS);

int countStart = oaAttendanceService.count(queryStart);

// 结束时间是否在节日假期范围内

LambdaQueryWrapper 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 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 算出下一个工作日_Java 计算一段时间段内除去周六日 节假日的工作日数———超详细(全)...

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