java计算⼯作时间除去节假⽇,双休⽇
package common.util;
DateFormat;
ParseException;
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
Time()&Time()){
return 0;
}
//开始时间到结束时间的完整星期数
int weekCount = (int) ((t2.getTime()-t1.getTime())/(milsecPerDay*7));
float totalHours = 0;
totalHours += weekCount * hoursPerWeek;
/
/调整结束时间,使开始时间和结束时间在⼀个星期的周期之内
t2.Time()-weekCount*7*milsecPerDay);
int dayCounts = 0;//记录开始时间和结束时间之间⼯作⽇天数
//调整开始时间,使得开始时间和结束时间在同⼀天,或者相邻的⼯作⽇内。
Time()<=t2.getTime()){
Date temp = new Time()+milsecPerDay);
temp = processBeginTime(temp);
temp.Hours());
temp.Minutes());
Time()&Time()){
break;
}else{
t1 = temp;
dayCounts++;
}
}
totalHours += dayCounts * hoursPerDay;
float hh1 = t1.getHours() + (Minutes()/60;
float hh1 = t1.getHours() + (Minutes()/60;
float hh2 = t2.getHours() + (Minutes()/60;
//处理开始结束是同⼀天的情况
Day()==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
* @return
*/
private Date processEndTime(Date t) {
float h = t.getHours() + (Minutes()/60;
//若结束时间晚于下午下班时间,将其设置为下午下班时间
if(h>=h4){
t.setHours(peh);
t.setMinutes(pem);
}else {
//若结束时间介于中午休息时间,那么设置为上午下班时间
if(h>=h2&&h<=h3){
t.setHours(aeh);
t.setMinutes(aem);
}else{
//若结束时间早于上午上班时间,⽇期向前推⼀天,并将时间设置为下午下班时间    Hours()<=h1){
t.Time()-milsecPerDay);
t.setHours(peh);
t.setMinutes(pem);
}
}
}
//若结束时间是周末,那么将结束时间向前推移到最近的⼯作⽇的下午下班时间
Day()==0){
t.Time()-milsecPerDay*(t.getDay()==6?1:2));
t.setHours(peh);
t.setMinutes(pem);
}
Day()==6){
t.Time()-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() + (Minutes()/60;
//若开始时间晚于下午下班时间,将开始时间向后推⼀天
if(h>=h4){
t.Time()+milsecPerDay);
t.setHours(abh);
t.setMinutes(abm);
}else {
//若开始时间介于中午休息时间,那么设置为下午上班时间
if(h>=h2&&h<=h3){
t.setHours(pbh);
t.setMinutes(pbm);
}else{
//若开始时间早于上午上班时间,将hour设置为上午上班时间
Hours()<=h1){
t.setHours(abh);
t.setMinutes(abm);
}
}
}
//若开始时间是周末,那么将开始时间向后推移到最近的⼯作⽇的上午上班时间
Day()==0){
t.Time()+milsecPerDay*(t.getDay()==6?2:1));
t.setHours(abh);
t.setMinutes(abm);
}Day()==6){
}Day()==6){
t.Time()+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);
java时间日期格式转换Calendar startDay = Instance();
Calendar endDay = Instance();
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 = Instance();
int (Calendar.YEAR); //获取当前年份
List<String> list = new ArrayList<String>();
for (String string : holiday) {
string=year+"-"+string;
list.add(string);
}
String[] arr = Array(new String[0]);
int holidays = arrContrast(workday, arr);
int holidayHous=holidays*8;
float  b  =  (float)(und(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 (!ains(str)) {
list.add(str);
}
}
for (String str : arr2) { //如果第⼆个数组存在和第⼀个数组相同的值,就删除
ains(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 (startDaypareTo(endDay) >= 0) {
return new String[]{};
}
// 现在打印中的⽇期
Calendar currentPrintDay = startDay;
while (true) {
// ⽇期加⼀
currentPrintDay.add(Calendar.DATE, 1);
// ⽇期加⼀后判断是否达到终了⽇,达到则终⽌打印
if (currentPrintDaypareTo(endDay) == 0) {
break;
}
list.add(FORMATTER.Time()));
}
String[] arr = Array(new String[0]);
return arr;
}
}
main⽅法中的执⾏结果为:
代码中都有注释,可⾃⾏根据需要进⾏调节