java计算工作时间除去节假日以及双休日

作者:旋转的钢笔 时间:2023-09-24 20:34:58 

本文实例为大家分享了java计算工作时间的具体代码,不包括节假日、双休日,供大家参考,具体内容如下


package common.util;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public class CalculateHours {
 SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); //这里的格式可以自己设置  
 //设置上班时间:该处时间可以根据实际情况进行调整
 int abh = 9;//上午上班时间,小时
 int abm = 00;//上午上班时间,分钟
 int aeh = 12;//上午下班时间,小时
 int aem = 0;//上午下班时间,分钟
 int pbh = 13;//下午上班时间,小时
 int pbm = 00;//下午上班时间,分钟
 int peh = 18;//下午下班时间,小时
 int pem = 0;//下午下班时间,分钟
 float h1 = abh+(float)abm/60;
 float h2 = aeh+(float)aem/60;
 float h3 = pbh+(float)pbm/60;
 float h4 = peh+(float)pem/60;
 float hoursPerDay = h2-h1+(h4-h3);//每天上班小时数
 int daysPerWeek = 5;//每周工作天数
 long milsecPerDay = 1000*60*60*24;//每天的毫秒数
 float hoursPerWeek = hoursPerDay*daysPerWeek;//每星期小时数
 public float calculateHours(String beginTime, String endTime){
   //对输入的字符串形式的时间进行转换
   Date t1 = stringToDate(beginTime);//真实开始时间
   Date t2 = stringToDate(endTime);//真实结束时间
   //对时间进行预处理
   t1 = processBeginTime(t1);
   t2 = processEndTime(t2);
   //若开始时间晚于结束时间,返回0
   if(t1.getTime()>t2.getTime()){
     return 0;
   }
   //开始时间到结束时间的完整星期数
   int weekCount = (int) ((t2.getTime()-t1.getTime())/(milsecPerDay*7));
   float totalHours = 0;
   totalHours += weekCount * hoursPerWeek;
   //调整结束时间,使开始时间和结束时间在一个星期的周期之内
   t2.setTime(t2.getTime()-weekCount*7*milsecPerDay);
   int dayCounts = 0;//记录开始时间和结束时间之间工作日天数
   //调整开始时间,使得开始时间和结束时间在同一天,或者相邻的工作日内。
   while(t1.getTime()<=t2.getTime()){
     Date temp = new Date(t1.getTime()+milsecPerDay);
     temp = processBeginTime(temp);
     temp.setHours(t1.getHours());
     temp.setMinutes(t1.getMinutes());
     if(temp.getTime()>t2.getTime()){
       break;
     }else{
       t1 = temp;
       dayCounts++;
     }
   }
   totalHours += dayCounts * hoursPerDay;
   float hh1 = t1.getHours() + (float)t1.getMinutes()/60;
   float hh2 = t2.getHours() + (float)t2.getMinutes()/60;
   //处理开始结束是同一天的情况
   if(t1.getDay()==t2.getDay()){
     float tt = 0;
     tt = hh2 - hh1;
     if(hh1>=h1&&hh1<=h2&&hh2>=h3){
       tt = tt - (h3-h2);
     }
     totalHours += tt;
   }else{
     //处理开始结束不是同一天的情况
     float tt1 = h4 - hh1;
     float tt2 = hh2 - h1;
     if(hh1<=h2){
       tt1 = tt1 - (h3-h2);
     }
     if(hh2>=h3){
       tt2 = tt2 - (h3-h2);
     }
     totalHours += (tt1 + tt2);
   }
   return totalHours;
 }

/**
  * 格式化输出时间: yyyy-mm-dd hh:mm:ss 星期x
  * @param t
  * @return
  */
 private String printDate(Date t) {
   String str;
   String xingqi = null;
   switch (t.getDay()) {
   case 0:
     xingqi = "星期天";
     break;
   case 1:
     xingqi = "星期一";
     break;
   case 2:
     xingqi = "星期二";
     break;
   case 3:
     xingqi = "星期三";
     break;
   case 4:
     xingqi = "星期四";
     break;
   case 5:
     xingqi = "星期五";
     break;
   case 6:
     xingqi = "星期六";
     break;
   default:
     break;
   }
   str = format.format(t)+" "+xingqi;
   return str;
 }

/**
  * 对结束时间进行预处理,使其处于工作日内的工作时间段内
  * @param t
  * @return
  */
 private Date processEndTime(Date t) {
   float h = t.getHours() + (float)t.getMinutes()/60;
   //若结束时间晚于下午下班时间,将其设置为下午下班时间
   if(h>=h4){
     t.setHours(peh);
     t.setMinutes(pem);
   }else {
     //若结束时间介于中午休息时间,那么设置为上午下班时间
     if(h>=h2&&h<=h3){
       t.setHours(aeh);
       t.setMinutes(aem);
     }else{
       //若结束时间早于上午上班时间,日期向前推一天,并将时间设置为下午下班时间
       if(t.getHours()<=h1){
         t.setTime(t.getTime()-milsecPerDay);
         t.setHours(peh);
         t.setMinutes(pem);
       }
     }
   }
   //若结束时间是周末,那么将结束时间向前推移到最近的工作日的下午下班时间
   if(t.getDay()==0){
     t.setTime(t.getTime()-milsecPerDay*(t.getDay()==6?1:2));
     t.setHours(peh);
     t.setMinutes(pem);
   }
   if(t.getDay()==6){
     t.setTime(t.getTime()-milsecPerDay*(t.getDay()==6?1:2));
     t.setHours(peh);
     t.setMinutes(pem);
   }
   return t;
 }
 /**
  * 对开始时间进行预处理
  * @param t1
  * @return
  */
 private Date processBeginTime(Date t) {
   float h = t.getHours() + (float)t.getMinutes()/60;
   //若开始时间晚于下午下班时间,将开始时间向后推一天
   if(h>=h4){
     t.setTime(t.getTime()+milsecPerDay);
     t.setHours(abh);
     t.setMinutes(abm);
   }else {
     //若开始时间介于中午休息时间,那么设置为下午上班时间
     if(h>=h2&&h<=h3){
       t.setHours(pbh);
       t.setMinutes(pbm);
     }else{
       //若开始时间早于上午上班时间,将hour设置为上午上班时间
       if(t.getHours()<=h1){
         t.setHours(abh);
         t.setMinutes(abm);
       }
     }
   }
   //若开始时间是周末,那么将开始时间向后推移到最近的工作日的上午上班时间
   if(t.getDay()==0){
     t.setTime(t.getTime()+milsecPerDay*(t.getDay()==6?2:1));
     t.setHours(abh);
     t.setMinutes(abm);
   }if(t.getDay()==6){
     t.setTime(t.getTime()+milsecPerDay*(t.getDay()==6?2:1));
     t.setHours(abh);
     t.setMinutes(abm);
   }
   return t;
 }

/**
  * 将字符串形式的时间转换成Date形式的时间
  * @param time
  * @return
  */
 private Date stringToDate(String time){
   try {
     return format.parse(time);
   } catch (ParseException e) {
     e.printStackTrace();
     return null;
   }
 }
 /**
  * 去除周末节假日工作小时
  * @param beginTime
  * @param endTime
  * @return
  * @throws ParseException
  */
 public static float CalculateHour(String beginTime,String endTime) throws ParseException{
   CalculateHours ch = new CalculateHours();
   float a=ch.calculateHours(beginTime, endTime);  
   Calendar startDay = Calendar.getInstance();
    Calendar endDay = Calendar.getInstance();
    startDay.setTime(FORMATTER.parse(beginTime));
    endDay.setTime(FORMATTER.parse(endTime));
   String[] workday=printDay(startDay, endDay);
   String[] holiday = new String[]{"01-01","01-02","01-03","05-01","05-02","05-03","10-01","10-02",
       "10-03","10-04","10-05","10-06","02-08","02-09","02-10"};
   Calendar now = Calendar.getInstance();  
   int year=now.get(Calendar.YEAR); //获取当前年份
   List<String> list = new ArrayList<String>();
   for (String string : holiday) {
     string=year+"-"+string;
     list.add(string);
   }
   String[] arr = list.toArray(new String[0]);
   int holidays = arrContrast(workday, arr);  
   int holidayHous=holidays*8;
   float b  = (float)(Math.round(a*10))/10;
   float workHours=b-holidayHous;
   return workHours;
 }
 public static void main(String[] args) throws ParseException {
   String beginTime = "2018-6-1 9:00:00";  
   String endTime = "2018-6-4 10:10:00";  
   CalculateHours ch = new CalculateHours();
   float b=ch.calculateHours(beginTime, endTime);
   System.out.println(b);
   float a=CalculateHours.CalculateHour(beginTime, endTime);
   System.out.println(a);
 }
 /**
  * 去除数组中相同日期
  * @param arr1
  * @param arr2
  * @return
  */
 private static int arrContrast(String[] arr1, String[] arr2){
   int count=0;
   List<String> list = new LinkedList<String>();
   for (String str : arr1) { //处理第一个数组,list里面的值为1,2,3,4
     if (!list.contains(str)) {
     list.add(str);
     }
   }
   for (String str : arr2) { //如果第二个数组存在和第一个数组相同的值,就删除
     if(list.contains(str)){
     list.remove(str);
     ++count;
     }
   }
   return count;
 }
 private static final DateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
 private static String[] printDay(Calendar startDay, Calendar endDay) {
    List<String> list = new ArrayList<String>();
    // 给出的日期开始日比终了日大则不执行打印
    if (startDay.compareTo(endDay) >= 0) {
     return new String[]{};
    }
  // 现在打印中的日期
  Calendar currentPrintDay = startDay;
  while (true) {
   // 日期加一
   currentPrintDay.add(Calendar.DATE, 1);
   // 日期加一后判断是否达到终了日,达到则终止打印
   if (currentPrintDay.compareTo(endDay) == 0) {
   break;
   }
   list.add(FORMATTER.format(currentPrintDay.getTime()));
  }
   String[] arr = list.toArray(new String[0]);
   return arr;
  }
}

main方法中的执行结果为:

java计算工作时间除去节假日以及双休日

代码中都有注释,可自行根据需要进行调节。

来源:https://blog.csdn.net/apbbbbb/article/details/80570053

标签:java,计算时间
0
投稿

猜你喜欢

  • 基于获取JAVA路径,包括CLASSPATH外的路径的方法详解

    2022-12-20 21:30:03
  • Android界面刷新的方法分享

    2022-06-20 15:20:52
  • Java动态代理详解及实例

    2023-12-08 15:51:03
  • 详解Android中Activity运行时屏幕方向与显示方式

    2022-02-12 03:51:06
  • MyBatis-Plus自动填充功能失效导致的原因及解决

    2023-05-11 13:16:08
  • java中List分页的几种方法介绍

    2022-03-01 12:04:28
  • java实现将数字转换成人民币大写

    2023-08-11 05:07:29
  • C# zxing二维码写入的实例代码

    2021-09-01 12:23:26
  • java 中模式匹配算法-KMP算法实例详解

    2022-01-30 09:08:08
  • C#简单创建和删除目录的方法

    2022-04-17 00:31:58
  • java8从list集合中取出某一属性的值的集合案例

    2023-04-30 01:51:49
  • java反射获取和调用方法

    2021-11-23 11:05:02
  • Spring Cloud Alibaba Nacos Config配置中心实现

    2022-08-02 00:43:05
  • Java 数据结构与算法系列精讲之二叉堆

    2022-05-14 06:31:15
  • springmvc实现简单的拦截器

    2022-02-27 05:13:39
  • Android自定义UI手势密码改进版源码下载

    2021-11-18 15:30:00
  • Android 游戏开发入门简单示例

    2023-05-02 07:29:56
  • Java+opencv3.2.0实现人脸检测功能

    2022-11-27 10:36:42
  • C#实现文件夹的复制和删除

    2023-02-18 00:54:22
  • Android常用正则表达式验证工具类(实例代码)

    2022-08-09 15:52:14
  • asp之家 软件编程 m.aspxhome.com