绪论

请假时长计算和每月工作天数计算其实六月份开发OA系统时就已经写出来了,只是一直没时间去整理,其实最近也很忙,毕竟年底要清一些开发任务。不过感觉自己今年博客写的太少了,所以这些日子基本每天都在加班,就是为了给自己抽出时间写一点博客。

逻辑

  1. 获取开始时间到结束时间之间所有的日期集合,去掉周末(list1)。
  2. 获取法定节假日(list2)、获取调休(list3)、获取部门作息时间。
  3. 删除时间区间中的所有法定节假日 list1.removeAll(list2)。
  4. 添加开始时间到结束时间之间的所有调休日期。
  5. 去重。
  6. 计算。

代码

MyData .java
package com.config;// 基础数据类,可从数据库获取
public class MyData {// 假期public static String[] holiday1 = { "2018-01-01", // 元旦"2018-02-15", // 春节"2018-02-16", // 春节"2018-02-17", // 春节"2018-02-18", // 春节"2018-02-19", // 春节"2018-02-20", // 春节"2018-02-21", // 春节"2018-04-05", // 清明节"2018-04-06", // 清明节"2018-04-07", // 清明节"2018-04-29", // 劳动节"2018-04-30", // 劳动节"2018-05-01", // 劳动节"2018-06-16", // 端午节"2018-06-17", // 端午节"2018-06-18", // 端午节"2018-09-22", // 中秋节"2018-09-23", // 中秋节"2018-09-24", // 中秋节"2018-10-01", // 国庆节"2018-10-02", // 国庆节"2018-10-03", // 国庆节"2018-10-04", // 国庆节"2018-10-05", // 国庆节"2018-10-06", // 国庆节"2018-10-07", // 国庆节"2018-12-31", // 元旦"2019-01-01" // 元旦};// 调休public static String[] holiday2 = { "2018-02-11", // 春节_调休"2018-02-24", // 春节_调休"2018-04-08", // 清明_节调休"2018-04-28", // 劳动_节调休"2018-09-29", // 国庆节_调休"2018-09-30", // 国庆节_调休"2018-12-29"  // 元旦_调休};// 作息时间1public static String[] workTime1 = { "08:30", // 上午上班时间"12:00", // 上午下班时间"13:00", // 下午上班时间"17:30"  // 下午下班时间};// 作息时间2public static String[] workTime2 = { "09:00", // 上午上班时间"12:00", // 上午下班时间"13:00", // 下午上班时间"18:00"  // 下午下班时间};
}
DateUtils.java
package com.utils;import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;import com.config.MyData;// 时间处理工作类
public class DateUtils {/*** 定义常见的时间格式*/private static String[] dateFormat = { "yyyy-MM-dd HH:mm:ss", // 0"yyyy/MM/dd HH:mm:ss", // 1"yyyy年MM月dd日HH时mm分ss秒", // 2"yyyy-MM-dd", // 3"yyyy/MM/dd", // 4"yy-MM-dd", // 5"yy/MM/dd", // 6"yyyy年MM月dd日", // 7"HH:mm:ss", // 8"yyyyMMddHHmmss", // 9"yyyyMMdd", // 10"yyyy.MM.dd", // 11"yy.MM.dd", // 12"MM月dd日HH时mm分", // 13"yyyy年MM月dd日 HH:mm:ss", // 14"yyyy-MM-dd HH:mm", // 15"yyMMdd" // 16};/*** 去重* * @param str* @return*/public static List<String> removal(List<String> str) {Set<String> s = new HashSet<String>(str);str.clear();str.addAll(s);return str;}/*** 获取两个日期之间的所有日期,去掉周末* * @param startDate* @param endDate* @return*/public static List<String> getDates(String startDate, String endDate) {List<String> result = new ArrayList<String>();Calendar startDay = Calendar.getInstance();Calendar endDay = Calendar.getInstance();startDay.setTime(StringToDate(startDate, 3));endDay.setTime(StringToDate(endDate, 3));while (startDay.before(endDay)) {int week = startDay.get(Calendar.DAY_OF_WEEK);if (7 != week && 1 != week) {result.add(dateToString(startDay.getTime(), 3));}startDay.add(Calendar.DAY_OF_YEAR, 1);}// 验证结束日期是否是周六周日int week = endDay.get(Calendar.DAY_OF_WEEK);if (7 != week && 1 != week) {result.add(dateToString(endDay.getTime(), 3));}return result;}/*** 字符串转时间* * @param dateStr* @param index* @return*/public static Date StringToDate(String dateStr, int index) {DateFormat df = null;try {df = new SimpleDateFormat(dateFormat[index]);return df.parse(dateStr);} catch (Exception aioe) {return null;}}/*** 时间转字符串* * @param date* @param index* @return*/public static String dateToString(Date date, int index) {if (date == null) {return null;}return new SimpleDateFormat(dateFormat[index]).format(date);}/*** 获取法定节假日或者调休* * @param num* @return*/public static List<String> holiday(int num) {if (num == 2) {return Arrays.asList(MyData.holiday2);} else {return Arrays.asList(MyData.holiday1);}}/*** 获取不同部门工作时间* * @param num* @return*/public static String[] workTime(int num) {if (num == 2) {return MyData.workTime2;} else {return MyData.workTime1;}}/*** 查询每个月的工作时间(天)** @return*/public static double queryMonthDay(String day) {List<String> result = new ArrayList<String>();Calendar Day = Calendar.getInstance();Day.setTime(StringToDate(day, 3));// 获取该月天数int dayNum = Day.getActualMaximum(Calendar.DAY_OF_MONTH);// 月开始String st = day.substring(0, 8) + "01";// 月结束String en = day.substring(0, 8) + dayNum;// 月份数据集合for (int i = 1; i < dayNum + 1; i++) {String d = day.substring(0, 8) + ((i < 10) ? "0" + i : "" + i);// 去掉周末Calendar startDay = Calendar.getInstance();startDay.setTime(StringToDate(d, 3));int week = startDay.get(Calendar.DAY_OF_WEEK);if (7 != week && 1 != week) {result.add(d);}}// 获取法定节假日List<String> fdList = holiday(1);// 获取调休List<String> txList = holiday(2);// 添加时间段中间应该上班的时间for (String s : txList) {if (s.compareTo(st) >= 0 && s.compareTo(en) <= 0) {result.add(s);}}// 去除中间所有的法定假期result.removeAll(fdList);// 去重result = removal(result);return result.size();}
}
LeaveManage.java
package com.leave;import java.util.Date;
import java.util.List;import com.utils.DateUtils;// 请假时长处理计算
public class LeaveManage {public static final LeaveManage manage = new LeaveManage();// 判断时间大小public double pdTime(String startTime, String endTime, int login) {int num = startTime.compareTo(endTime);if (num > 0) {return calculationTime(endTime, startTime, login);} else if (num < 0) {return calculationTime(startTime, endTime, login);} else {return 0;}}public double calculationTime(String startTime, String endTime, int login) {// 获取startTime和endTime之间的所有日期,去掉周六周日List<String> list = DateUtils.getDates(startTime, endTime);// 获取法定节假日List<String> fdList = DateUtils.holiday(1);// 获取调休List<String> txList = DateUtils.holiday(2);// 上班时间String[] workTime = DateUtils.workTime(login);// 删除时间区间中的所有法定节假日list.removeAll(fdList);String st = startTime.substring(0, 10);String en = endTime.substring(0, 10);for (String s : txList) {if (s.compareTo(st) >= 0 && s.compareTo(en) <= 0) {// 添加时间区间中的所有调休日期list.add(s);}}// 去重list = DateUtils.removal(list);// 开始当天上午上班时间、上午下班时间、下午上班时间、下午下班时间String amWorkYes = startTime.substring(0, 11) + workTime[0];String amWorkNo = startTime.substring(0, 11) + workTime[1];String pmWorkYes = startTime.substring(0, 11) + workTime[2];String pmWorkNo = startTime.substring(0, 11) + workTime[3];// 结束当天上午上班时间、上午下班时间、下午上班时间、下午下班时间String amWorkYesEnd = endTime.substring(0, 11) + workTime[0];String amWorkNoEnd = endTime.substring(0, 11) + workTime[1];String pmWorkYesEnd = endTime.substring(0, 11) + workTime[2];String pmWorkNoEnd = endTime.substring(0, 11) + workTime[3];double time = 0;if (list.size() == 0) {// 申请日期是法定节假日return time;} else if (list.size() == 1) {// 请假一天if (startTime.compareTo(pmWorkNo) > 0) {return time;}if (endTime.compareTo(amWorkYes) < 0) {return time;}if (startTime.compareTo(amWorkNo) >= 0 && endTime.compareTo(pmWorkYes) <= 0) {return time;}if (startTime.compareTo(amWorkYes) < 0) {startTime = amWorkYes;}if (endTime.compareTo(pmWorkNo) > 0) {endTime = pmWorkNo;}if (startTime.compareTo(amWorkNo) >= 0 && startTime.compareTo(pmWorkYes) <= 0) {startTime = pmWorkYes;}if (endTime.compareTo(amWorkNo) >= 0 && endTime.compareTo(pmWorkYes) <= 0) {endTime = amWorkNo;}Date start = DateUtils.StringToDate(startTime, 15); // 0或者15Date end = DateUtils.StringToDate(endTime, 15);// 三种情况,1:请假时间全在上午,2:请假时间全在下午,3:包含午休时间if (startTime.compareTo(amWorkYes) >= 0 && endTime.compareTo(amWorkNo) <= 0) {double minute = (end.getTime() - start.getTime()) / (1000 * 60);time = minute / (8 * 60);} else if (startTime.compareTo(pmWorkYes) >= 0 && endTime.compareTo(pmWorkNo) <= 0) {double minute = (end.getTime() - start.getTime()) / (1000 * 60);time = minute / (8 * 60);} else if (startTime.compareTo(amWorkNo) < 0 && endTime.compareTo(pmWorkYes) > 0) {double minute = (end.getTime() - start.getTime()) / (1000 * 60) - 60;time = minute / (8 * 60);}return time;} else {// 处理请假多天的情况// 申请开始时间处理if (list.contains(st)) {if (startTime.compareTo(amWorkYes) < 0) {startTime = amWorkYes;}if (startTime.compareTo(pmWorkNo) > 0) {startTime = pmWorkNo;}if (startTime.compareTo(amWorkNo) >= 0 && startTime.compareTo(pmWorkYes) <= 0) {startTime = pmWorkYes;}Date start = DateUtils.StringToDate(startTime, 15); // 0或者15Date end = DateUtils.StringToDate(pmWorkNo, 15);if (startTime.compareTo(amWorkNo) < 0) {// 减去中午一小时double t = (end.getTime() - start.getTime()) / (1000 * 60) - 60;time = time + t / (8 * 60);} else {double t = (end.getTime() - start.getTime()) / (1000 * 60);time = time + t / (8 * 60);}list.remove(st);}// 申请结束时间处理if (list.contains(en)) {if (endTime.compareTo(amWorkYesEnd) < 0) {endTime = amWorkYesEnd;}if (endTime.compareTo(pmWorkNoEnd) > 0) {endTime = pmWorkNoEnd;}if (endTime.compareTo(amWorkNoEnd) >= 0 && endTime.compareTo(pmWorkYesEnd) <= 0) {endTime = amWorkNoEnd;}Date end = DateUtils.StringToDate(endTime, 15);// 0或者15Date start = DateUtils.StringToDate(amWorkYesEnd, 15);if (endTime.compareTo(pmWorkYesEnd) > 0) {double t = (end.getTime() - start.getTime()) / (1000 * 60) - 60;time = time + t / (8 * 60);} else {double t = (end.getTime() - start.getTime()) / (1000 * 60);time = time + t / (8 * 60);}list.remove(en);}// 天数计算集合中剩下的个数就可以time = time + list.size();return time;}}
}
Main.java
package com.leave;import com.utils.DateUtils;public class Main {static LeaveManage manage = LeaveManage.manage;public static void main(String[] args) {System.out.println("1、正常工作日请假:" + manage.calculationTime("2018-12-21 08:30", "2018-12-24 17:30", 1));System.out.println("2、带调休请假:" + manage.calculationTime("2018-12-27 08:30", "2018-12-29 17:30", 1));System.out.println("3、法定节假日请假:" + manage.calculationTime("2018-09-24 08:30", "2018-09-26 17:30", 1));System.out.println("4、跨年请假:" + manage.calculationTime("2018-12-29 08:30", "2019-01-02 17:30", 1));System.out.println("2018年01月上班天数:" + DateUtils.queryMonthDay("2018-01-10"));System.out.println("2018年02月上班天数:" + DateUtils.queryMonthDay("2018-02-10"));System.out.println("2018年03月上班天数:" + DateUtils.queryMonthDay("2018-03-10"));System.out.println("2018年04月上班天数:" + DateUtils.queryMonthDay("2018-04-10"));System.out.println("2018年05月上班天数:" + DateUtils.queryMonthDay("2018-05-10"));System.out.println("2018年06月上班天数:" + DateUtils.queryMonthDay("2018-06-10"));System.out.println("2018年07月上班天数:" + DateUtils.queryMonthDay("2018-07-10"));System.out.println("2018年08月上班天数:" + DateUtils.queryMonthDay("2018-08-10"));System.out.println("2018年09月上班天数:" + DateUtils.queryMonthDay("2018-09-10"));System.out.println("2018年10月上班天数:" + DateUtils.queryMonthDay("2018-10-10"));System.out.println("2018年11月上班天数:" + DateUtils.queryMonthDay("2018-11-10"));System.out.println("2018年12月上班天数:" + DateUtils.queryMonthDay("2018-12-10"));}}

结果

由于源码涉及到的内容比较多,无法粘贴出来,所以又新写了一遍。其中法定节假日和调休可以用SQL语句(用开始和结束时间约束)从数据库获取,对于不同作息时间的员工,可以实现单独处理。

源代码下载地址

(若有什么错误,请留言指正,3Q)

请假时长计算和每月工作天数计算相关推荐

  1. 【泛微表单】请假流程中计算请假时长(非系统自带考勤类型)

    请假流程计算请假时长 按一天8小时计算,日期为浏览按钮日期字段,时间为单选下拉框: <script> var beginTimeId = {id: "field22286&quo ...

  2. Java计算请假时长(根据规则设置去除节假日、休息日、特殊日期)

    首先选择的日期要判断是不是节假日: 这里是写了工具类获取全年的日期信息. dateUtils工具类 某年第一天可以直接拼接 yyyy-01-01 获取节假日方法: public class DateU ...

  3. JS实现请假时长计算(计算小时数差)

    给公司做了一套系统,涉及到请假单功能开发.在计算请假时长这块总结一下:按天计算的就不总结了比较简单,这里总结一下按小时数计算的 ,话不多说,直接上代码 // 获取两个日期相差的工作小时(不包括节假日) ...

  4. JavaScript 实现页面内时间实时倒计时 计时器内附完整文件欢迎调用(可用于抢购倒计时,记录恋爱纪念日总时长等)输出对应的天数小时分钟秒数

    JavaScript 实现页面内时间倒计时 计时器 可用于抢购倒计时,记录恋爱纪念日总时长等输出对应的天数小时分钟秒数 注意:在下一个文章中将公布一个纪念日成品代码,欢迎各位来学习(复制) 第一步:构 ...

  5. java 计算有效时长,有一时间段不计算时长

    java 计算有效时长,有一时间段不计算时长 计算时效性 计算 2020-08-07 10:10:23 到 2020-08-08 22:10:23 时间段内有多少小时,每天的01:00:00至06:0 ...

  6. SQL 计算每个月的工作天数

    在考勤应用中,经常会有每月工作天数.公休天数.出勤天数的计算. 当月工作天数=当月天数 - 当月星期六天数 - 当月星期天天数 我们通过DATEDIF.DATEPART这两个函数运算得出. selec ...

  7. 统计app用户在线时长_「云工作普及系列」2.如何实时统计工作时长,提高工作效率

    记上节我们讲了[1.如何注册云工作平台]之后,接下来一起探索下该平台提供的各个产品功能.今天主要讲一下如何它的实时统计工作时长是怎么实现的? 我们先来了解一下它的工作时长实时统计的功能. 一,从web ...

  8. QuantLib 金融计算——基本组件之天数计算规则详解

    目录 天数计算规则详解 定义 30 / 360 法 30/360 US 30/360 Bond Basis 30E/360 30E/360 ISDA Actual 法 Actual/Actual IC ...

  9. Java计算每月工作天数

    本代码经测试完全可以使用,仅提供demo做参考 import java.text.DateFormat; import java.text.SimpleDateFormat; import java. ...

最新文章

  1. php循环输出sql数组吗,在PHP中循环SQL结果 – 没有获得整个数组
  2. JavaScript中的匿名函数及函数的闭包
  3. MySQL Binlog三种格式介绍及分析
  4. oracle 单表查询 详细图文
  5. 下列选项中 采用边界值平滑_数据挖掘期末考题(答案).doc
  6. POJ1236 Network of Schools
  7. Echarts地图编写
  8. 工作117:eachat图
  9. Lync Server 2010标准版系列PART6:启用Lync
  10. mac 鼓捣php 多版本切换
  11. 自动轮播图html代码适应手机,JS实现自动轮播图效果(自适应屏幕宽度+手机触屏滑动)...
  12. [POI2012]STU-Well(二分答案+神仙操作)
  13. 基于FPGA板的音乐盒的设计
  14. Daily reflection|腾讯云测评第一阶段汇报
  15. 整合+策略:微网通联的GMP平台如何帮助企业搭建统一智慧通信架构
  16. 【AI产品】前沿黑科技,安利一款能让你的照片动起来的app
  17. codeforces1194B Yet Another Crosses Problem 思维
  18. NBA表格_NBA球星大排位16—季后赛荣誉汇总
  19. 2021年中国人工智能企业数量、投资数量及金额分析:国内互联网巨头腾讯企业投资达82家[图]
  20. SpringBoot整合Mybatis(配置文件)

热门文章

  1. 根据关键词批量获取淘宝商品链接并保存图片
  2. AndroidStudio嵌入Unity
  3. 磁盘分区MBR和GPT
  4. 如何连接惠普台式计算机蓝牙,hp笔记本蓝牙怎么设置【详解】
  5. 你真的了解自己的计算机吗?
  6. 苹果原壁纸高清_苹果X壁纸 | 全面屏壁纸高清
  7. 电商项目顺序图_工程项目文件的分类整理
  8. ScanNet数据集讲解与点云数据下载
  9. v880+ 手机自用软件介绍
  10. 北京酒仙桥兆维电信机房简介