OA请假自动计算请假时长(只计算工作日时长,剔除周末以及法定节假日等)
程序员文章站
2022-05-18 19:39:21
...
标题
作为一个刚开始进入编程工作的小白,这也是我的第一篇博客,其实这点业务对于大牛来说可能分分钟搞定的事,小白的我却花了2天擦搞定。
话不多少说,进正题!!!先说说我的业务需求:做了一个关于OA请假的流程申请,其中涉及了请假时长计算的问题,在前台选开始/结束时间,然后自动计算请假天数。其中8:30-11:30 13:30-17:30为工作时间,请假>=2小时为0天;2小时<时间<=4小时为0.5天;时间>4小时为1天。
其中除婚假,产假,探亲假外,只计算有效工作时间内的时长(系统自动剔除周末及法定节假日,调休等)!
此项目因为是之前老项目,所以用的Struts2,还有就是JSP里面使用好多公司封装的组件,所以大请假只拿自己有用的就好了!
前台jsp
function SumDays() {
//关于前两行大家可以使用自己的获取两个时间(此处我是使用公司自己组件得到两个
yyyy-mm-dd hh:mm:ss格式时间)
var beginTime = ajaxform1.getColumnValue("beginTime");
var endTime = ajaxform1.getColumnValue("endTime");
//截取到月份
var starttimeleft=beginTime.substring(0,10);
var endtimeleft=endTime.substring(0,10);
//获取毫秒数
var bDate = (new Date(beginTime)).getTime();
var eDate = (new Date(endTime)).getTime();
if(eDate < bDate){
setRM("error","结束日期不能小于开始日期! ");
}
//次函数是获取两个时间量内所有的日期(jsp通用)
function dateAll(startTimes,endTimes){
var date_all=[],i=0;
function getDate(datestr){
var temp = datestr.split("-");
var date = new Date(temp[0],temp[1]-1,temp[2]);
return date;
}
var start = startTimes;
var end = endTimes;
var startTime = getDate(start);
var endTime = getDate(end);
while((endTime.getTime()-startTime.getTime())>=0){
var year = startTime.getFullYear();
var month = (startTime.getMonth()+1).toString().length==1?"0"+(startTime.getMonth()+1).toString():(startTime.getMonth()+1).toString();
var day = startTime.getDate().toString().length==1?"0"+startTime.getDate():startTime.getDate();
date_all[i]=year+"-"+month+"-"+day;
startTime.setDate(startTime.getDate()+1);
i+=1;
}
return date_all;
}
//得到两个日期内所有的日期
var dates = "";
var dateAll = dateAll(starttimeleft,endtimeleft);
for(var i=0;i<dateAll.length;i++){
dates += dateAll[i]+",";
}
//获取form表单内所有的数据
var data = ajaxform1.collectData(true);
var dataArr = [];
dataArr.push(data);
//回传到后台JAVA程序处理
$.request({
action : "check",
data : dataArr,
params : {
dates : dates,
beginTime : beginTime,
endTime : endTime
},
success : ajax_init
}) ;
}
后台JAVA
我的思路是:在后台得到前台传过来的选的开始/结束时间、两日期内所有的日期三个参数,循环遍历所有日期,再利用法定节假日接口,以此判断是否是节假日,周末等等。最终根据请假小时数计算天数
public void check() throws Exception{
//得到form表单里的实体数据(此处大家可使用自己的,我使用的公司的封装体)
SzglOaQj szglOaQj = dataWrap.getData();
if (SzglCommonUtil.strIsNull(szglOaQj.getQjType())) {
throw new BaseConfirmException("请先选择请假类型!");
}
//得到开始的小时
Double starHour =Double.parseDouble( beginTime.substring(11, 13)+"."+beginTime.substring(14, 16));
//得到结束的小时
Double endHour =Double.parseDouble( endTime.substring(11, 13)+"."+endTime.substring(14, 16));
//得到两日期内所有的日期
List<String> dateList = SzglCommonUtil.paraseIdsStr(getDates());
Double travelTimeHours = 0.0;
//遍历所有日期
for (int i = 0; i < dateList.size(); i++) {
String date = dateList.get(i);
/*此处调用了网上的法定节假日接口,大家靠自行查阅资料
(返回的JSON格式的数据,常工作日对应结果为 0, 法定节假日对应结果为 1,
节假日调休补班对应的结果为 2,休息日对应结果为 3)*/
String url="http://api.goseek.cn/Tools/holiday";
try {
//最终s为JSON数据解析的值
String s = "";
String dateD = date.replace("-", "");
String request="date="+dateD;
//getData方法参阅下面
String response=getData(url,request);
JSONObject object = new JSONObject(response);
if (!object.isNull("data")) {
s = object.getString("data");
//判断是否是婚假、产假、探亲假
if (szglOaQj.getQjType().equals("05") || szglOaQj.getQjType().equals("08")
|| szglOaQj.getQjType().equals("09")) {
if(starHour < 8.30){
starHour = 8.30;
}
if(starHour > 17.30){
starHour = 17.30;
}
if(endHour < 8.30){
endHour = 8.30;
}
if(endHour > 17.30){
endHour = 17.30;
}
//如果为第一天则计算当天的请假小时数
if (i == 0) {
if (starHour <= 11.30) {
travelTimeHours += (11.30-starHour+4);
}else if (starHour > 11.30 && starHour < 13.30) {
travelTimeHours += 4;
}else if (starHour >= 13.30) {
travelTimeHours += (17.30-starHour);
}
}
//计算最后一天的请假小时数
if (i == dateList.size()-1) {
if (endHour <= 11.30) {
travelTimeHours += (endHour-8.30);
}else if (endHour > 11.30 && endHour < 13.30) {
travelTimeHours += 3;
}else if (endHour >= 13.30) {
travelTimeHours += (endHour - 13.30 + 3.0);
}
}
//中间的天直接计算7小时工作日
if (i != 0 && i != dateList.size()-1) {
travelTimeHours += 7;
}
}else {
//只计算工作日内小时数
if (s.equals("0")) {
//是否是同一天(isSameDay方法放在了最后)
if (SzglCommonUtil.isSameDay(beginTime, endTime)) {
if (starHour <= 11.30) {
if (8.30<= endHour && endHour<13.30) {
if((endHour-starHour) <= 2){
szglOaQj.setDays(new BigDecimal(0));
}else if ((endHour-starHour) > 2) {
szglOaQj.setDays(new BigDecimal(0.5));
}
}else if (endHour>13.30) {
if(((endHour-starHour)-2)<=2){
szglOaQj.setDays(new BigDecimal(0));
}else if(2<((endHour-starHour)-2)&&((endHour-starHour)-2)<=4){
szglOaQj.setDays(new BigDecimal(0.5));
}else if(((endHour-starHour)-2) > 4){
szglOaQj.setDays(new BigDecimal(1));
}
}
}else if (starHour >= 13.30) {
if((endHour-starHour) <= 2){
szglOaQj.setDays(new BigDecimal(0));
}else if((endHour-starHour) > 2){
szglOaQj.setDays(new BigDecimal(0.5));
}
}
}else {//如果不是同一天
if(starHour < 8.30){
starHour = 8.30;
}
if(starHour > 17.30){
starHour = 17.30;
}
if(endHour < 8.30){
endHour = 8.30;
}
if(endHour > 17.30){
endHour = 17.30;
}
if (i == 0) {
if (starHour <= 11.30) {
travelTimeHours += (11.30-starHour+4);
}else if (starHour > 11.30 && starHour < 13.30) {
travelTimeHours += 4;
}else if (starHour >= 13.30) {
travelTimeHours += (17.30-starHour);
}
}
if (i == dateList.size()-1) {
if (endHour <= 11.30) {
travelTimeHours += (endHour-8.30);
}else if (endHour > 11.30 && endHour < 13.30) {
travelTimeHours += 3;
}else if (endHour >= 13.30) {
travelTimeHours += (endHour - 13.30 + 3.0);
}
}
if (i != 0 && i != dateList.size()-1) {
travelTimeHours += 7;
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*根据所有小时数计算请假天数,取商则为天数,再取余判断是否超过了规定的小时数*/
int times = (int) (travelTimeHours / 7);
Double time = (travelTimeHours % 7) ;
if (time <= 2) {
szglOaQj.setDays(new BigDecimal(times));
}else if (2 < time && time <= 4) {
szglOaQj.setDays(new BigDecimal(times+0.5));
}else if (4 < time){
szglOaQj.setDays(new BigDecimal(times+1));
}
//最终返回了前台显示
dataWrap.setData(szglOaQj);
responseData.setAjaxDataWrap("dataWrap", dataWrap);
}
//网上接口的调用需要发送请求,此处是发送请求方法
public static String getData(String url, String request)throws UnsupportedEncodingException, IOException {
String charset = "UTF-8";
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
HttpURLConnection connect = (HttpURLConnection) (new URL(url).openConnection());
connect.setRequestMethod("GET");
connect.setDoOutput(true);
connect.setConnectTimeout(1000 * 10);
connect.setReadTimeout(1000 * 80);
connect.setRequestProperty("ContentType", "application/x-www-form-urlencoded"); //采用通用的URL百分号编码的数据MIME类型来传参和设置请求头
connect.setDoInput(true);
// 连接
connect.connect();
// 发送数据
connect.getOutputStream().write(request.getBytes(charset));
// 接收数据
int responseCode = connect.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream in = connect.getInputStream();
byte[] data = new byte[1024];
int len = 0;
while ((len = in.read(data, 0, data.length)) != -1) {
outStream.write(data, 0, len);
}
in.close();
}
// 关闭连接
connect.disconnect();
String response = outStream.toString("UTF-8");
return response;
}
是否是同一天的判断方法
public static boolean isSameDay(String day1, String day2) {
String time1 = day1.substring(0, 10);
String time2 = day2.substring(0, 10);
if (time1.equals(time2)) {
return true;
}else {
return false;
}
}
因为开发框架的原因,和大家的使用肯定有所不同,能用的拿走不谢,大家参考里面的思路就好了!