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

本文实例为大家分享了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方法中的执行结果为:

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java计算时间差的方法

    本文实例讲述了java计算时间差的方法.分享给大家供大家参考.具体如下: /** * 计算时间差 * @param begin * @param end * @return 返回格式,"hh:mm:ss" */ public String getTimeDifference(Date begin,Date end) { long between=(end.getTime()-begin.getTime())/1000; //除以1000是为了转换成秒 long hour=between

  • Java中计算时间差的方法

    本文实例讲述了Java中计算时间差的方法.分享给大家供大家参考.具体如下: 假设现在是2004-03-26 13:31:40 过去是:2004-01-02 11:30:24 要获得两个日期差,差的形式为:XX天XX小时XX分XX秒 方法一: DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date d1 = df.parse("2004-03-26 13:31:40"); Date

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

    本文实例为大家分享了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; impo

  • java计算两个日期之前的天数实例(排除节假日和周末)

    如题所说,计算两个日期之前的天数,排除节假日和周末.这里天数的类型为double,因为该功能实现的是请假天数的计算,有请一上午假的为0.5天. 不够很坑的是每个日期都要查询数据库,感觉很浪费时间. 原则: 1.节假日存放在数据库中 实现步骤: 1.循环每个日期 2.判断每个日期是否为节假日或者为周末 3.若不是节假日和周末,天数+1 代码: public double calLeaveDays(Date startTime,Date endTime){ double leaveDays = 0;

  • Java计算两个程序运行时间的实例

    一.获取系统当前时间 long startTime = System.currentTimeMillis(); //获取开始时间 doSomething(); //测试的代码段 long endTime = System.currentTimeMillis(); //获取结束时间 System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间 二.以纳秒为单位计算 // 第二种是以纳秒

  • java计算两个日期中间的时间

    java计算两个日期中间的时间 其中在数据库中有一个字段为datetime类型,想要计算两个日期之间过了多少天 多少小时 多少分钟. 思路为把时间换算为毫秒(与协调世界时 1970 年 1 月 1 日午夜之间的时间差(以毫秒为单位测量).然后利用毫秒的加减计算. 计算如下: public static String getDays(Date date){ Calendar cal=Calendar.getInstance(); cal.setTime(date); long oldTime=ca

  • java计算给定字符串中出现次数最多的字母和该字母出现次数的方法

    本文实例讲述了java计算给定字符串中出现次数最多的字母和该字母出现次数的方法.分享给大家供大家参考,具体如下: import Java.util.Collections; import java.util.Map; import java.util.TreeMap; public class TestStringSplict { public static void main(String[] args){ String str = "aaaaaaacccccccccccccccccccccc

  • java计算两个时间相差天数的方法汇总

    问题描述: 输入:两个日期 输出:两个日期相差的天数 具体代码实现 方法1: 通过Calendar类的日期比较.注意:这里需要考虑一下: 日期是跨年份的,如一个是2012年,一个是2015年的 年份是分闰年和平年的,各自的天数不同 /** * date2比date1多的天数 * @param date1 * @param date2 * @return */ public static int differentDays(Date date1,Date date2) { Calendar cal

  • java计算百分比值的方法

    本文实例讲述了java计算百分比值的方法.分享给大家供大家参考.具体实现方法如下: public class Test1 { public static String myPercent(int y, int z) { String baifenbi = "";// 接受百分比的值 double baiy = y * 1.0; double baiz = z * 1.0; double fen = baiy / baiz; // NumberFormat nf = NumberForm

  • Java计算交集,差集,并集的方法示例

    本文实例讲述了Java计算交集,差集,并集的方法.分享给大家供大家参考,具体如下: package math; import java.util.HashSet; import java.util.Set; public class Test { public static void main(String[] args) { Set<Integer> result = new HashSet<Integer>(); Set<Integer> set1 = new Ha

  • Java计算黑洞数的方法示例

    本文实例讲述了Java计算黑洞数的方法.分享给大家供大家参考,具体如下: 任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到一个最大的数:65432,一个最小的数23456.求这两个数字的差,得:41976,把这个数字再次重复上述过程(如果不足5位,则前边补0).如此往复,数字会落入某个循环圈(称为数字黑洞). 比如,刚才的数字会落入:[82962,75933, 63954, 61974]这个循环圈. 请编写程序,找到5位数所有可能的循环圈,并输出,每个循环圈占1行.其中5

随机推荐