绪论

请假时长计算和每月工作天数计算其实六月份开发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. The Third Revolution in Sequencing Technology
  2. 一个资深技术人的转型之路
  3. 疯狂捕鱼之路径解决方案的思考
  4. WinCE启动次数的记录
  5. nyoj 47 江 河问题 【贪婪】
  6. 被黑客盯上了…数据都给打包带走了…
  7. 数据库迁移mysql到sqlserver_数据库迁移(sqlserver至mysql)
  8. 鸿蒙系统正式开源,余承东:鸿蒙系统正式开源,友商也可以使用!
  9. 读取模式错误,计算引擎操作复杂……面对Hadoop这些问题该如何应对?
  10. 活动目录的介绍:深入浅出Active Directory系列(一)
  11. 基于Springboot的医院药品管理系统的设计与实现.zip(论文+项目源码)
  12. Python调用腾讯API进行营业执照核验
  13. 在matlab使用矩阵的方法计算DFT
  14. 【HTML期末学生大作业】 制作一个简单HTML保护野生动物老虎网页设计专题(HTML+CSS)
  15. 软件版本 —— Alpha、Beta、RC版本的区别
  16. 实训小笔记之—产品经理能力模型
  17. 8b10b编码源码 matlab,8b/10b编码技术系列(一):Serdes、CDR、K码
  18. live555 android,live555
  19. RE合同记账会计凭证
  20. 阿里宣布组织大变动:集团迎来首位 80 后 CTO、张勇亲自挂帅阿里云!

热门文章

  1. 主对角占优矩阵的结论与应用
  2. 中企动力与港田高分子同行 创建营销型企业云平台
  3. 《炬丰科技-半导体工艺》LED 封装工艺
  4. 在钉钉上怎么手写_数码知识:钉钉手写签名如何设置开启手写签名教程
  5. Matlab:绘制虚数和复数数据图
  6. MATLAB应用FFT算法对图形进行处理
  7. 耗材管理平台环境配置
  8. win7+ubuntu14.04双系统出现的问题及解决办法
  9. [实战]用flutter编写炸弹人小游戏同时支持web和移动端
  10. 【爬虫实战项目】Python爬虫批量下载评书音频并保存本地(附源码)