java 排除法定节假日以及正常周六日,计算两个Date相差的小时数

您所在的位置:网站首页 考勤小时数怎么算天数和天数 java 排除法定节假日以及正常周六日,计算两个Date相差的小时数

java 排除法定节假日以及正常周六日,计算两个Date相差的小时数

2024-06-28 04:58| 来源: 网络整理| 查看: 265

项目组有一个需求,计算两个Date类型参数,相差的小时数。业务上有一些特殊的用途,可能用于绩效考核的目的吧…

如果不排除节假日周六日的话,处理起来非常easy,是个程序员都能写出来,但是…如果要排除法定节假日,排除正常周六日,同时特殊支持法定的工作日(有一些周六日,国家强制正常上班),那么处理起来就非常麻烦,我耗时大概1天半的时间,用基础的Date和Calendar实现,下面是具体的实现代码,要是有更好的实现,欢迎大家留言。

注意:项目组要求如果开始或者截止时间属于休息日,对应当天处理小时数为0。例如:2018-2-14 8:00:00 到2018-2-15 10:00:00,2-15是国家规定放假时间,不算时间,只算2-14号的16个小时。可以根据你们自己项目组的需求,灵活的修改哦

/** * 判断输入的年月日日期是否属于休息日 * @param date 需要判断的日期(年月日) * @param lawHolidayList 国家规定放假的时间 * @param lawWorkList 国家规定的工作日期 * @return */ public static boolean isDayOff(Date date,List lawHolidayList,List lawWorkList){ for(Date date1 :lawHolidayList){ int c = date.compareTo(date1); if(c==0){ //休息日 return true; } } for(Date date1 :lawWorkList){ int c = date.compareTo(date1); if(c==0){ //工作日 return false; } } return isZhouLiuZhouRiDate(date); } /** * 判断时间是否属于正常周六日 * @param date * @return */ public static boolean isZhouLiuZhouRiDate(Date date){ Calendar cal = Calendar.getInstance(); cal.setTime(date); int week = cal.get(Calendar.DAY_OF_WEEK) - 1; //是否属于周六日 boolean flag = (week == 0 || week == 6); return flag; } /** * 排除国家法定的休息日、正常周六日,计算两个时间相差多少小时数(休息日当天时间为零处理) * @param startTimeYYYYMMDDHHMMSS 年月日时分秒 * @param endTimeYYYYMMDDHHMMSS 年月日时分秒 * @param lawHolidayList * @param lawWorkList * @return */ public static long workHours(Date startTimeYYYYMMDDHHMMSS, Date endTimeYYYYMMDDHHMMSS, List lawHolidayList, List lawWorkList) throws Exception { //开始时间转成年月日格式 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String strStartTimeYYYYMMDD = sdf.format(startTimeYYYYMMDDHHMMSS); Date startTimeYYYYMMDD = sdf.parse(strStartTimeYYYYMMDD); //开始时间是否属于休息日 boolean startTimeIsDayOff = isDayOff(startTimeYYYYMMDD, lawHolidayList, lawWorkList); //结束时间转成年月日格式 String strEndTimeYYYYMMDD = sdf.format(endTimeYYYYMMDDHHMMSS); Date endTimeYYYYMMDD = sdf.parse(strEndTimeYYYYMMDD); //结束时间是否属于休息日 boolean endTimeIsDayOff = isDayOff(endTimeYYYYMMDD, lawHolidayList, lawWorkList); //分为4种情况 if (startTimeIsDayOff) { if (!endTimeIsDayOff) { //开始时间在休息日里,结束时间不在休息日里(开始那天不计算小时数,结束那天计算小时数) Calendar cal = Calendar.getInstance(); cal.setTime(startTimeYYYYMMDD); cal.add(Calendar.DAY_OF_MONTH, +1); Date validStartTimeYYYYMMDD = cal.getTime(); Date validStartTimeYYYYMMDDTemp = validStartTimeYYYYMMDD; int skipDay = 0; //循环遍历开始时间之后的每一个日期 while (validStartTimeYYYYMMDDTemp.compareTo(endTimeYYYYMMDDHHMMSS) != 1) { if (isDayOff(validStartTimeYYYYMMDDTemp, lawHolidayList, lawWorkList)) { skipDay += 1; } cal.add(Calendar.DAY_OF_MONTH, +1); validStartTimeYYYYMMDDTemp = cal.getTime(); } return ((endTimeYYYYMMDDHHMMSS.getTime() - validStartTimeYYYYMMDD.getTime()) / (60 * 60 * 1000)) - skipDay * 24; } else { //开始时间在休息日里,结束时间也在休息日里(开始那天不计算小时数,结束那天也不计算小时数,看中间有多少个工作日) Calendar cal = Calendar.getInstance(); cal.setTime(startTimeYYYYMMDD); cal.add(Calendar.DAY_OF_MONTH, +1); Date validStartTimeYYYYMMDD = cal.getTime(); //工作日天数 int workDays = 0; //循环遍历开始时间之后的每一个日期 while (validStartTimeYYYYMMDD.compareTo(endTimeYYYYMMDDHHMMSS) != 1) { if (!isDayOff(validStartTimeYYYYMMDD, lawHolidayList, lawWorkList)) { workDays += 1; } cal.add(Calendar.DAY_OF_MONTH, +1); validStartTimeYYYYMMDD = cal.getTime(); } return workDays * 24; } } else { if (endTimeIsDayOff) { int skipDay = 0; //开始时间不在休息日里,结束时间在休息日里 Calendar cal = Calendar.getInstance(); cal.setTime(startTimeYYYYMMDD); cal.add(Calendar.DAY_OF_MONTH, +1); Date validStartTimeYYYYMMDD = cal.getTime(); while (validStartTimeYYYYMMDD.compareTo(endTimeYYYYMMDDHHMMSS) != 1) { if (!isDayOff(validStartTimeYYYYMMDD, lawHolidayList, lawWorkList)) { skipDay += 1; } cal.add(Calendar.DAY_OF_MONTH, +1); validStartTimeYYYYMMDD = cal.getTime(); } Calendar ca = Calendar.getInstance(); ca.setTime(startTimeYYYYMMDDHHMMSS); int startHour = ca.get(Calendar.HOUR_OF_DAY); return (24-startHour) + skipDay * 24; } else { //开始时间在不在休息日里,结束时间也不在休息日里 int skipDay = 0; Calendar cal = Calendar.getInstance(); cal.setTime(startTimeYYYYMMDD); cal.add(Calendar.DAY_OF_MONTH, +1); Date validStartTimeYYYYMMDD = cal.getTime(); while (validStartTimeYYYYMMDD.compareTo(endTimeYYYYMMDDHHMMSS) != 1) { if (isDayOff(validStartTimeYYYYMMDD, lawHolidayList, lawWorkList)) { skipDay += 1; } cal.add(Calendar.DAY_OF_MONTH, +1); validStartTimeYYYYMMDD = cal.getTime(); } return ((endTimeYYYYMMDDHHMMSS.getTime() - startTimeYYYYMMDDHHMMSS.getTime()) / (60 * 60 * 1000)) - skipDay * 24; } } } public static void main(String args[]) throws Exception{ SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd"); List lawHolidayDate = new ArrayList(); List lawWorkDate = new ArrayList(); String [] lawHolidayDateStr = new String[] { "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-30", "2018-12-31", "2019-01-01", "2019-02-04", "2019-02-05", "2019-02-06", "2019-02-07", "2019-02-08", "2019-02-09", "2019-02-10", "2019-04-05", "2019-04-06", "2019-04-07", "2019-05-01", "2019-06-07", "2019-06-08", "2019-06-09", "2019-09-13", "2019-09-14", "2019-09-15", "2019-10-01", "2019-10-02", "2019-10-03", "2019-10-04", "2019-10-05", "2019-10-06", "2019-10-07"}; String [] lawWorkDateStr = new String[] { "2018-02-11", "2018-02-24", "2018-04-08", "2018-04-28", "2018-09-29", "2018-09-30", "2018-12-29", "2019-02-02", "2019-02-03", "2019-09-29", "2019-10-12"}; for(String str :lawHolidayDateStr){ lawHolidayDate.add(yyyyMMdd.parse(str)); } for(String str :lawWorkDateStr){ lawWorkDate.add(yyyyMMdd.parse(str)); } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date startDate = sdf.parse("2018-02-22 8:45:10"); Date endDate = sdf.parse("2018-02-24 7:10:10"); System.out.println("相差小时数:"+workHours(startDate,endDate,lawHolidayDate,lawWorkDate)); }

上面的例子,需要在项目里配置两种时间,一是国家法律规定的休息的时间,二是国家规定要正常上班的时间(例如一些周六日,为了十一的一天放假,调休前一个或者后一个周六日必须上班)。上面的例子是直接写死的2018/2019年的两种时间,自己项目的话,可以配置在配置文件或者数据库中哦!



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3