Java计算⼀段时间段内除去周六⽇、节假⽇的⼯作⽇数———超详细(全)Java 计算⼀段时间段内除去周六⽇、节假⽇的⼯作⽇数‘’
实现功能提要: 本⽂章记录的是某段时间的起⽌时间段内的⼯作⽇,既是除去周六周⽇以及节假⽇⽇期的⼯作⽇数;
注释⽐较多,因为怕⾃⼰忘记,写的可能⽐较啰嗦~;
1、前端界⾯简介
其他的先不考虑,主要是由前台传递到后台的假期开始时间和结束时间;
2、后台处理代码
此段直接进⼊正题,处理代码我封装到Utils⼯具类中了,因此关于接收前台时间数据、⽅法的调⽤以及参数的传递就不在细说,只提⼀点就是:传到⼯具类中的参数有三个,分别是假期开始、假期结束时间以及假期信息表的service对象~
代码部分:
package cn.ikdo.oa.leave.utils;
/**
* @Descript: ⼯作⽇计算
*/
DateFormat;
ParseException;
周六日可以汽车年审吗SimpleDateFormat;
import java.util.Date;
import ditions.query.LambdaQueryWrapper;
import lkit.Wrappers;
import cn.ity.OaAttendanceVacation; // 假期信息实体类
import cn.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 Time());
Date endDates = new Time());
/*
此段主要是为了达到半天请假记录的处理,⽐如我是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 startparam = formatter.parse(dfStart);
Date endparam = formatter.parse(dfEnd);
// 每次循环的都查看计算⽇期是否超出结束⽇期
while (startparampareTo(endparam) <= 0) {
// 参与判断⽇期的星期码不等于周六且不等于周⽇的星期码
if (Day() != 6 && Day() != 0) {
// 此处需要注意,本⼈使⽤的去除节假⽇⽇期的⽅法是先将节假⽇的信息(主要
//是节⽇假期起⽌时间)放⼊到数据库中,然后通过循环⽐对参与判断的⽇期是否在某个节⽇假期时间内;
// 创建⼀个查询条件对象(没有此⽅法的可以⾃⼰⼿动将查询条件传递给SQL)
LambdaQueryWrapper<OaAttendanceVacation> query = Wrappers.lambdaQuery();
// 参与判断的⽇期⼤于等于节⽇假期的开始时间条件(OaAttendanceVacation为假期的实体对象,StartDay是假期开始时间) query.le(OaAttendanceVacation::getStartDay, startparam);
// 参与判断的⽇期⼩于等于节⽇假期的开始时间条件(EndDay是假期截⽌时间)
<(OaAttendanceVacation::getEndDay, startparam);
// 通过count⽅法查询是否存在符合条件的
int count = unt(query);
// 若是count仍为0,则说明没有符合条件的,进⼀步说就是参与判断的⽇期不是节假⽇
if (count == 0) {
// ⼯作⽇计数参数加⼀
result++;
}
}
// 此天判断玩完了,对当前⽇期进⾏加⼀操作,使其变成下⼀天的⽇期参与下⼀轮判断
startparam.Date() + 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();
<(OaAttendanceVacation::getStartDay, paramS);
queryStart.le(OaAttendanceVacation::getEndDay, paramS);
int countStart = unt(queryStart);
// 结束时间是否在节⽇假期范围内
LambdaQueryWrapper<OaAttendanceVacation> queryEnd = Wrappers.lambdaQuery(); (OaAttendanceVacation::getStartDay, paramE);
queryEnd.le(OaAttendanceVacation::getEndDay, paramE);
int countEnd = unt(queryEnd);
// 判断开始时间不是周六⽇或节假⽇
if (Day() != 6 && Day() != 0 && countStart == 0) {
result = result - 1F;
} else {// 开始时间在周六⽇或节假⽇
if (s < 12) {
result = result - 1F;
} else {
result = result - 0.5F;
}
}
// 结束时间不是周六⽇或节假⽇
if (Day() != 6 && Day() != 0 && countEnd == 0) {
result = result - 1F;
} else {// 结束时间在周六⽇或节假⽇
if (e < 12) {
result = result - 0.5F;
} else {
result = result - 1F;
}
}
} else {// 起⽌时间在同⼀天的情况下
// 开始时间是否处于假期内,只需要查询开始时间或者结束时间即可
LambdaQueryWrapper<OaAttendanceVacation> queryStart = Wrappers.lambdaQuery(); (OaAttendanceVacation::getStartDay, paramS);
queryStart.le(OaAttendanceVacation::getEndDay, paramS);
int countStart = unt(queryStart);
// 此天⾮节假⽇、周六⽇
if (Day() != 6 && Day() != 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.DAY_OF_WEEK) 取代,但是暂时还能⽤,有兴趣的可以换成Calendar试试;
另外,⾥⾯有⼏段代码使⽤频率⽐较⾼,有兴趣的可以封装成⽅法直接调⽤;
pass:
代码中主要是⾃⼰的思路,可能有点啰嗦,就是怕⾃⼰以后再看费劲,想着这会⿇烦点,以后轻松点~
感悟:
不要对不会的代码⼼⾥排斥,多看别⼈的代码,勇于⾯对⾃⼰的弱点、问题,只有这样才能让⾃⼰进步!
《END》
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论