java 排除法定节假日以及正常周六日,计算两个Date相差的小时数
生活随笔
收集整理的這篇文章主要介紹了
java 排除法定节假日以及正常周六日,计算两个Date相差的小时数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
項目組有一個需求,計算兩個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<Date> lawHolidayList,List<Date> 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<Date> lawHolidayList,List<Date> 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<Date> lawHolidayDate = new ArrayList<>();List<Date> 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年的兩種時間,自己項目的話,可以配置在配置文件或者數據庫中哦!
總結
以上是生活随笔為你收集整理的java 排除法定节假日以及正常周六日,计算两个Date相差的小时数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html新闻轮播插件,jQuery新闻类
- 下一篇: IxChariot 6.7 endpoi