实现去除非工作日和非工作时间的时间工具类,亲测可用:
最近在工作中遇到这样一个开发需求,废话不多说,直接上代码
#代码如下
package com.example.demo;
import org.springframework.boot.SpringApplication;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
/**
* @Author:奚XI
* @Destription:
* @Data:Crerted in 14:232022/5/4
* @Modified by:
**/
public class HolidayUtils {
/**
* @param startTime 开始时间
* @param timeout 要超时的分钟
* @param lawHolidayList 节假日List '2022-05-01,2022-05-02'
* @return 超时的结束时间
*/
public static String getOutTime(String startTime, int timeout, List<String> lawHolidayList) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
String startTimeH = format.format(sdf.parse(startTime));
String[] workingTimes = "08:30-12:00,13:30-18:00".split(",");
String morning = workingTimes[0];
String afternoon = workingTimes[1];
String[] mornings = morning.split("-");
String[] afternoons = afternoon.split("-");
/**
* 如果不在工作时间内设置成工作时间内的分钟,
* 开始时间的分钟0-8:30 设置成8:30
* 12:00-13:30设置成13:30
* 18:00-24:00 设置成18:00
*/
startTime = resetTimelnWorkTime(startTime, startTimeH, mornings, afternoons);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime startTimeLocal = LocalDateTime.parse(startTime, dateTimeFormatter);
/**
* 如果开始时间是非工作日则把当前开始时间向后延期到后后一天的工作开始时间
* 如果延后之后的时候大于结束时间返回0
*/
while (lawHolidayList.contains(startTimeLocal.format(dateTimeFormatter).substring(0, 10))) {
startTimeLocal = startTimeLocal.plusDays(1);
startTime = startTimeLocal.format(dateTimeFormatter).substring(0, 11).concat(mornings[0]).concat(":00");
startTimeH = format.format(sdf.parse(startTime));
startTimeLocal = LocalDateTime.parse(startTime, dateTimeFormatter);
}
int days = timeout / 480;
int minus = timeout % 480;
if (days > 0) {
startTimeLocal = getLocalDateTimeAddDays(lawHolidayList,dateTimeFormatter,startTimeLocal,days);
startTimeLocal = startTimeLocal.plusMinutes(minus);
startTime = startTimeLocal.format(dateTimeFormatter);
}
/** *如果当天的最后
工作时间-开始时间的分钟
>minus(timeout % 480)
*那么就要判断增加后
nift
的时间是否在上午的工作分钟
内,如果超过上午的工作分钟
*则要添加中午的非工
作时间的分钟
因
*如果超过下午的最后
工作时间要加上到第二天开始时
间的值
*/
startTimeLocal = startTimeLocal.plusMinutes(minus);
startTime = startTimeLocal.format(dateTimeFormatter);
long startMinute
= sdf.parse(startTime.substring(0, 11).concat(
mornings[1]).concat(":00")).getTime();
long endTMinute
= sdf.parse(startTime.substring(0, 11).concat(afternoons[0])
.concat(":00")).getTime();
if (startTime.substring(11, 16).compareTo(mornings[1]) > 0
&& startTime.substring(11, 16).compareTo(afternoons[0]) < 0) {
startTimeLocal = startTimeLocal.plusMinutes((
endTMinute - startMinute) / (1000 * 60L));
startTime = startTimeLocal.format(dateTimeFormatter);
/**结束时间分钟在
05:30-10:00 开始时间在上午
工作时间结束时间在下午金
工作时间结束时间在下午
*/
} else if
(startTime.substring(11, 16).compareTo(afternoons[0]) > 0 && startTime.substring(11, 16).compareTo(afternoons[1]) < 0 && startTimeH.compareTo(mornings[1]) < 0) {
startTimeLocal = startTimeLocal.plusMinutes((endTMinute - startMinute) / (1000 * 60L));
startTime = startTimeLocal.format(dateTimeFormatter);
}
else if
(startTime.substring(11, 16).compareTo(afternoons[1]) > 0) {
startTime = startTimeLocal.format(dateTimeFormatter);
long startMin = sdf.parse(startTime.substring(0, 11)
.concat(afternoons[1]).concat(":00")).getTime();
LocalDateTime newStartTimeLocal
= startTimeLocal.plusDays(1);
long endTMin = sdf.parse(newStartTimeLocal.
format(dateTimeFormatter).substring(0, 11)
.concat(mornings[0]).concat(":00"))
.getTime();
long minTime = (endTMin - startMin) / (1000 * 60L);
startTimeLocal = startTimeLocal.plusMinutes(minTime);
startTime = startTimeLocal.format(dateTimeFormatter);
if (startTime.substring(11, 16).compareTo(mornings[1]) > 0 &&
startTime.substring(11, 16).compareTo(afternoons[1]) < 0) {
startTimeLocal =
startTimeLocal.plusMinutes((endTMinute - startMinute) / (1000 * 60L));
startTime =
startTimeLocal.format(dateTimeFormatter);
startTime = startTimeLocal.format(dateTimeFormatter).substring(0, 10);
startTimeLocal =
startTimeLocal.plusDays(1);
startTime =
startTimeLocal.format(dateTimeFormatter);
}
}
} catch (ParseException e) {
e.printStackTrace();
}
return startTime;
}
private static LocalDateTime getLocalDateTimeAddDays(List<String> lawHolidayList,
DateTimeFormatter dateTimeFormatter, LocalDateTime startTimeLocal, int days) {
for (int i = 0; i < days; i++) {
startTimeLocal = startTimeLocal.plusDays(1);
while
(lawHolidayList.contains(startTimeLocal.format(dateTimeFormatter).substring(0, 10))) {
startTimeLocal = startTimeLocal.plusDays(1);
}
}
return startTimeLocal;
}
public static int newWorkMinutes(String startTime, String endTime, List<String> lawHolidayList) {
try {
if (endTime.compareTo(startTime) <= 0) {
return 0;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
String startTimeH = formatter.format(sdf.parse(startTime));
String endTimeH = formatter.format(sdf.parse(endTime));
String[] workingTimes = "08:30-12:00,13:30-18:00".split(",");
String morning = workingTimes[0];
String afternoon = workingTimes[1];
String[] mornings = morning.split("-");
String[] afternoons = afternoon.split("-");
/**
*如果不在工作时间内设置成工作时间内的分钟
*开始时间的分
钟 0 - 8:30 设置成8:30
12.00 - 13.30 设置成 12:00
18:00 - 24.00 设置成18:00
* 结束时间的分
钟 0 - 8:30 设置成8:30
12.00 - 13.30 设置成 12:00
18:00 - 24.00 设置成18:00
*/
startTime = resetTimelnWorkTime(startTime, startTimeH, mornings, afternoons);
endTime = resetTimelnWorkTime(endTime, endTimeH, mornings, afternoons);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime startTimeLocal = LocalDateTime.parse(startTime, dateTimeFormatter);
LocalDateTime endTimeLocal = LocalDateTime.parse(endTime, dateTimeFormatter);
/**
*如果开始时间是非工
作日则把当前开始时间向后延期
到后一天的工作开始时间
* 如果延后之后的时候
大于结束时间返回0
初
*/
while (lawHolidayList.contains(startTimeLocal.
format(dateTimeFormatter).substring(0, 10))) {
startTimeLocal = startTimeLocal.plusDays(1);
startTime = startTimeLocal.format(dateTimeFormatter).substring(0, 11)
.concat(mornings[0]).concat(":00");
startTimeLocal = LocalDateTime.parse(startTime, dateTimeFormatter);
if (startTimeLocal.isAfter(endTimeLocal)) {
return 0;
}
}
/**
*如果结束时间是非工
作日则把当前结束时间向前延期
到前一天的工作结束时间
网
*/
while (lawHolidayList.contains(endTimeLocal.format(dateTimeFormatter)
.substring(0, 10))) {
endTimeLocal = endTimeLocal.minusDays(1);
endTime = endTimeLocal.format(dateTimeFormatter).substring(0,
11).concat(afternoons[1]).concat(":00");
endTimeLocal = LocalDateTime.parse(endTime, dateTimeFormatter);
}
startTimeH = formatter.format(sdf.parse(startTime));
endTimeH = formatter.format(sdf.parse(endTime));
/***
*如果节假日被包含在
开始时间和结束时间中通过计
算出来的分钟值直接减去即可
团
*/
long holidayCount = 0L;
long holidaySumCount = 0L;
while (startTimeLocal.isBefore(endTimeLocal)) {
String dateStr = startTimeLocal.format(dateTimeFormatter);
if (lawHolidayList.contains(dateStr.substring(0, 10))) {
holidayCount = holidayCount + 1;
holidaySumCount = holidaySumCount + 1;
}
startTimeLocal = startTimeLocal.plusDays(1);
}
long startTimeL = sdf.parse(startTime).getTime();
long endTimeL = sdf.parse(endTime).getTime();
long minTime = endTimeL / (1000 * 60L) -
startTimeL / (1000 * 60L);
long dayTime = minTime / (24 * 60L);
startTime = startTimeLocal.format(dateTimeFormatter);
long startMinute = sdf.parse(startTime.substring(0, 11).concat(afternoons[1])
.concat(":00")).getTime();
LocalDateTime nextStartTimeLocal = startTimeLocal;
nextStartTimeLocal = nextStartTimeLocal.plusDays(1);
long endTMinute = sdf.parse(nextStartTimeLocal.format(dateTimeFormatter)
.substring(0, 11).concat(mornings[0]).concat(":00")).getTime();
long nexTime = (endTMinute - startMinute) / (1000 * 60L);
long startTimeMinute = sdf.parse(startTime.substring(0, 11).concat(
mornings[1]).concat(":00")).getTime();
long endTimeMinute = sdf.parse(startTime.substring(0, 11)
.concat(afternoons[0]).concat(":00")).getTime();
nexTime = nexTime + (endTimeMinute - startTimeMinute)
/ (1000 * 60L);
//如果开始时间>结束时间且不在同一天
if (startTimeH.compareTo(endTimeH) > 0) {
dayTime = dayTime + 1;
}
long timeDifference;
if (holidayCount == 0) {
timeDifference = minTime - dayTime * nexTime;
} else {
timeDifference
= minTime - (dayTime -
holidayCount) * nexTime -
holidaySumCount * 24 * 60L;
}
/***
*如果开始时间的分钟
在上午,结束时间的分钟在下
午,则要减去中午的非工作时间
* 如果开始时间的分钟
在下午,结束时间的分钟在上午
则要加上中午的非工作时间
团
*/
if (startTimeH.compareTo(mornings[1]) <= 0 &&
endTimeH.compareTo(afternoons[0]) >= 0) {
timeDifference = timeDifference -
(endTimeMinute - startTimeMinute) / (1000 * 60L);
} else if (startTimeH.compareTo(afternoons[0])
>= 0 && endTimeH.compareTo(mornings[1]) <= 0){
timeDifference = timeDifference +
(endTimeMinute - startTimeMinute) / (1000 * 60L);
}
return (int) timeDifference;
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}
private static String resetTimelnWorkTime(String startTime, String startTimeH, String[] mornings, String[] afternoons) {
if (startTimeH.compareTo("00:00") >= 0 && startTimeH.compareTo(mornings[0]) < 0) {
startTime = startTime.substring(0, 11).concat(mornings[0]).concat(":00");
} else if (startTimeH.compareTo(mornings[1])
> 0 && startTimeH.compareTo(afternoons[0]) <= 0) {
startTime = startTime.substring(0, 11).concat(mornings[1]).concat(":00");
} else if (startTimeH.compareTo(mornings[1]) > 0 && startTimeH.compareTo(afternoons[0]) <= 0) {
startTime = startTime.substring(0, 11).concat(mornings[1]).concat(":00");
} else if (startTimeH.compareTo(afternoons[1]) > 0) {
startTime = startTime.substring(0, 11).concat(afternoons[1]).concat(":00");
}
return startTime;
}
public static void main(String[] args) {
List<String> lawHolidayList=new ArrayList<>();
lawHolidayList.add("2022-05-01");
lawHolidayList.add("2022-05-02");
lawHolidayList.add("2022-05-03");
lawHolidayList.add("2022-05-04");
System.out.println(getOutTime( "2022-05-06 07:00:00", 240,lawHolidayList ));
System.out.println(getOutTime( "2022-05-04 09:00:00", 10,lawHolidayList ));
System.out.println(newWorkMinutes("2022-05-06 07:00:00","2022-05-06 14:00:00",lawHolidayList));
System.out.println(newWorkMinutes("2022-05-04 09:00:00","2022-05-05 08:40:00",lawHolidayList));
System.out.println(newWorkMinutes("2022-05-05 08:00:00","2022-05-05 08:40:00",lawHolidayList));
System.out.println(newWorkMinutes("2022-05-04 09:00:00","2022-05-06 08:40:00",lawHolidayList));
}
}