计算两个时间之间的工作时长(小时)排除周末
package com.test;
import org.apache.commons.lang3.time.DateUtils;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Demo1 {
public static void main(String[] args) throws ParseException {
String startTime = "2023-01-19 11:00";
String endTime = "2023-01-22 17:00";
Date startMoningStart = getDate(startTime,1);
Date startMoningEnd = getDate(startTime,2);
Date startAfternoonStart = getDate(startTime,3);
Date startAfternoonEnd = getDate(startTime,4);
Date endMoningStart = getDate(endTime,1);
Date endMoningEnd = getDate(endTime,2);
Date endAfternoonStart = getDate(endTime,3);
Date endAfternoonEnd = getDate(endTime,4);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date start = format.parse(startTime);
Date end = format.parse(endTime);
int hours = 1000*60*60;
float result = 0;
//若开始时间和结束时间是同一天
SimpleDateFormat simple1 = new SimpleDateFormat("yyyy-MM-dd");
simple1.format(simple1.parse(startTime)).equals(simple1.format(simple1.parse(endTime)));
if(simple1.format(simple1.parse(startTime)).equals(simple1.format(simple1.parse(endTime)))){
//如果结束时间比上班时间早,或者结束时间比开始时间早 或者开始时间晚于下午下班时间,则出差时长为0
if(end.getTime() <= startMoningStart.getTime() || end.getTime()<=start.getTime() || start.getTime()>=startAfternoonEnd.getTime()
|| isHolidays(startTime)){
result = 0;
System.out.println("出差时长为:"+result);
return;
}
//如果结束时间在上午时间段
if(end.getTime()<=startMoningEnd.getTime()){
//判断开始时间是否早与上午上班时间
if(start.getTime()<startMoningStart.getTime()){
result = (end.getTime()-startMoningStart.getTime()+0f)/hours;
}else{
result = (end.getTime()-start.getTime()+0f)/hours;
}
}
//如果结束时间在中午时间段
if(end.getTime()>startMoningEnd.getTime() && end.getTime()<=startAfternoonStart.getTime()){
//如果开始时间在上午上班之前
if(start.getTime()<=startMoningStart.getTime()){
result = 4;
}else if(start.getTime()>startMoningStart.getTime() && start.getTime()<startMoningEnd.getTime()){
//开始时间在上午上班时间段
result = (startMoningEnd.getTime()-start.getTime()+0f)/hours;
} else if (start.getTime()>=startMoningStart.getTime()) {
//开始时间也在中午
result = 0;
}
}
//如果结束时间在下午上班时间段
if(end.getTime()>startAfternoonStart.getTime() && end.getTime()<=startAfternoonEnd.getTime()){
if(start.getTime()<=startMoningStart.getTime()){
//如果开始时间在上午上班之前
result = 4 + (end.getTime()-startAfternoonStart.getTime()+0f)/hours;
} else if (start.getTime()>startMoningStart.getTime() && start.getTime()<startMoningEnd.getTime()) {
//如果开始时间在上午上班时间
result = (startMoningEnd.getTime()-start.getTime() + end.getTime()-startAfternoonStart.getTime()+0f)/hours;
} else if (start.getTime()>=startMoningEnd.getTime() && start.getTime()<=startAfternoonStart.getTime()) {
//开始时间在中午时间段
result = (end.getTime() - startAfternoonStart.getTime()+0f)/hours;
}else if(start.getTime()>startAfternoonStart.getTime()){
//开始时间也在下午上班时间段
result = (end.getTime()-start.getTime()+0f)/hours;
}
}
//如果结束时间在下午下班之后
if(end.getTime() > startAfternoonEnd.getTime()){
if(start.getTime() <= startMoningStart.getTime()){
//如果开始时间在上午上班之前
result = 8;
}else if(start.getTime()>startMoningStart.getTime() && start.getTime()<startMoningEnd.getTime()){
//开始时间在上午上班时间段
result = 4 + (startMoningEnd.getTime() - start.getTime()+0f)/hours;
} else if (start.getTime()>=startMoningEnd.getTime() && start.getTime()<=startAfternoonStart.getTime()) {
//如果开始时间在中午时间段
result = 4;
} else if (start.getTime()>startAfternoonStart.getTime() && start.getTime()<startAfternoonEnd.getTime()) {
//开始时间在下午上班时间段
result = (startAfternoonEnd.getTime()-start.getTime()+0f)/hours;
}
}
}else {
if( end.getTime()<=start.getTime() ){
result = 0f;
System.out.println("出差时长为:"+result);
return;
}
//开始时间和结束时间不在同一天
float startDayHours = getStartDayHours(start,startMoningStart,startMoningEnd,startAfternoonStart,startAfternoonEnd);
float endDayHours = 8 - getStartDayHours(end,endMoningStart,endMoningEnd,endAfternoonStart,endAfternoonEnd);
//计算开始时间和结束时间之间隔了几天
int days = getDays(startTime,endTime);
float daysHours = (days-1)*8;
result = daysHours + startDayHours + endDayHours;
result = deleteHolidays(startTime,endTime,startDayHours,endDayHours,result);
}
BigDecimal bigResult = new BigDecimal(result);
float finalResult = bigResult.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
System.out.println("出差时长为:"+finalResult);
}
//排除出差时长中的节假日时间 这里不考虑休息半天的情况
// 开始时间startTime 结束时间endTime 开始时间当前的时长startDayHours 结束时间当天的时长endDayHours 排除节假日之前的时长
//只有startTime 和endTime不在同一天才调用
private static float deleteHolidays(String startTime,String endTime,float startDayHours,float endDayHours, float hours) throws ParseException {
float result = hours+0f;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//1判断startTime是否是节假日,周末
if(isHolidays(startTime)){
result = result - startDayHours;
}
//轮循开始时间到结束时间 当前时间
String nowDate = startTime;
do{
nowDate = format.format(DateUtils.addDays(format.parse(nowDate), 1));
if(format.format(format.parse(nowDate)).equals(format.format(format.parse(endTime)))){
break;
}
if(isHolidays(nowDate)){
result = result - 8;
}
}while(true);//
if(isHolidays(endTime)){
result = result -endDayHours;
}
return result;
}
//判断一个日期是否是节假日 或者周末
private static boolean isHolidays(String time) throws ParseException {
String queryCalenderSql = "";
//IRowSet query = DbUtil.executeQuery(ctx, queryCalenderSql);
// if(query.next()){
// return true;
// }
//判断是否是周末
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.setTime(format.parse(time));
if(cal.get(Calendar.DAY_OF_WEEK)==1 || cal.get(Calendar.DAY_OF_WEEK)==7){
return true;
}
return false;
}
private static int getDays(String startTime,String endTime) throws ParseException {
//计算开始和结束时间之间相差的天数
int result = 0;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date start = format.parse(startTime);
Date end = format.parse(endTime);
Calendar calStart = Calendar.getInstance();
calStart.setTime(start);
Calendar calEnd = Calendar.getInstance();
calEnd.setTime(end);
int startDay = calStart.get(Calendar.DAY_OF_YEAR);
int endDay = calEnd.get(Calendar.DAY_OF_YEAR);
int yearStart = calStart.get(Calendar.YEAR);
int yearEnd = calEnd.get(Calendar.YEAR);
if(yearEnd != yearStart) //不同年
{
int timeDistance = 0 ;
for(int i = yearStart ; i < yearEnd ; i ++)
{
if(i%4==0 && i%100!=0 || i%400==0) //闰年
{
timeDistance += 366;
}
else //不是闰年
{
timeDistance += 365;
}
}
System.out.println(timeDistance + (endDay-startDay));
result = timeDistance + (endDay-startDay);
}
else //同一年
{
result = endDay-startDay;
System.out.println("判断day2 - day1 : " + (endDay-startDay));
//return day2-day1;
}
return result;
}
//计算开始时间那天的出差时长
private static float getStartDayHours(Date start,Date moningStart,Date moningEnd,Date afternoonStart,Date afternoonEnd){
float result = 0f;
//开始时间早与上午上班时间
if(start.getTime()<=moningStart.getTime()){
result = 8;
}else if(start.getTime()>moningStart.getTime() && start.getTime() <moningEnd.getTime()){
//开始时间在上午时间段
result = 4 + (moningEnd.getTime()-start.getTime()+0f)/(1000*60*60);
} else if (start.getTime()>=moningEnd.getTime() && start.getTime()<=afternoonStart.getTime()) {
//开始时间在中午时间段
result = 4;
}else if(start.getTime()>afternoonStart.getTime() && start.getTime()<afternoonEnd.getTime()){
result = (afternoonEnd.getTime() - start.getTime()+0f)/(1000*60*60);
}else if(start.getTime()>=afternoonEnd.getTime()){
result = 0;
}
return result;
}
//获取给定日期工作时间
private static Date getDate(String date, int type) throws ParseException {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
calendar.setTime(format.parse(date));
StringBuilder result = new StringBuilder();
if(calendar.get(Calendar.MONTH)<9){
result.append(calendar.get(Calendar.YEAR)).append("-0");
}else{
result.append(calendar.get(Calendar.YEAR)).append("-");
}
result.append(calendar.get(Calendar.MONTH)+1).append("-");
result.append(calendar.get(Calendar.DATE)).append(" ");
//1上午开始时间08:30 ;2上午结束时间12:30 3下午开始时间13:00 4下午结束时间17:00
switch (type){
case 1:result.append("08:30");
break;
case 2:result.append("12:30");
break;
case 3:result.append("13:00");
break;
case 4:result.append("17:00");
break;
}
return format.parse(String.valueOf(result));
}
}
如果要再排除节假日,可以从数据库中查询,减去节假日的时间就可以了