JAVA 需求背景 1.传入日常工作时间段为字符串(HH:mm-HH:mm;HH:mm-HH:mm;HH:mm-HH:mm) 2.传入剩余可用工作时间段为字符串(HH:mm-HH:mm;HH:mm-HH:mm;HH:mm-HH:mm) 3.传入需要的工作时间(分) 3.判断是否有可用工作时间段的时间满足需要工作时间 如果有 返回满足的时间段中最早的时间段 4.需考虑可用工作时间段中 存在有两个相邻的时间段的第一个时间段的结束时间和第二个时间段的开始时间和日常工作时间一样 这种情况这两个相邻的时间段需要算作一个连续的时间段 代码要有详细注释
时间: 2024-02-07 15:01:48 浏览: 24
好的,根据您提供的需求背景,我可以为您提供以下 JAVA 代码实现:
```
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class WorkTime {
/**
* 判断是否有可用工作时间段的时间满足需要工作时间
* 如果有 返回满足的时间段中最早的时间段
* @param dailyTime 日常工作时间段字符串
* @param availableTime 剩余可用工作时间段字符串
* @param needTime 需要的工作时间(分钟)
* @return 返回满足的时间段中最早的时间段
*/
public static String findAvailableTime(String dailyTime, String availableTime, int needTime) {
// 将日常工作时间段字符串解析为时间段列表
List<TimePeriod> dailyList = parseTimePeriod(dailyTime);
// 将剩余可用工作时间段字符串解析为时间段列表
List<TimePeriod> availableList = parseTimePeriod(availableTime);
// 将相邻的时间段合并为一个连续的时间段
mergeTimePeriod(availableList, dailyList);
// 遍历可用工作时间段列表,找到满足需要工作时间的最早时间段
for (TimePeriod tp : availableList) {
Date startTime = tp.getStartTime();
Date endTime = tp.getEndTime();
// 如果时间段长度大于等于需要工作时间,则返回该时间段的字符串表示
if (endTime.getTime() - startTime.getTime() >= needTime * 60 * 1000) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
return sdf.format(startTime) + "-" + sdf.format(endTime);
}
}
// 没有满足需要工作时间的时间段,返回空字符串
return "";
}
/**
* 将时间段字符串解析为时间段列表
* @param timeStr 时间段字符串
* @return 时间段列表
*/
private static List<TimePeriod> parseTimePeriod(String timeStr) {
List<TimePeriod> list = new ArrayList<>();
String[] arr = timeStr.split(";");
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
for (String s : arr) {
String[] t = s.split("-");
try {
Date startTime = sdf.parse(t[0]);
Date endTime = sdf.parse(t[1]);
list.add(new TimePeriod(startTime, endTime));
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
/**
* 将相邻的时间段合并为一个连续的时间段
* @param list 时间段列表
* @param dailyList 日常工作时间段列表,用于判断相邻时间段是否需要合并
*/
private static void mergeTimePeriod(List<TimePeriod> list, List<TimePeriod> dailyList) {
// 将时间段列表按照开始时间排序
list.sort((o1, o2) -> o1.getStartTime().compareTo(o2.getStartTime()));
// 遍历时间段列表,合并相邻的时间段
for (int i = list.size() - 2; i >= 0; i--) {
TimePeriod tp1 = list.get(i);
TimePeriod tp2 = list.get(i + 1);
Calendar calendar = Calendar.getInstance();
calendar.setTime(tp1.getEndTime());
calendar.add(Calendar.MINUTE, 1);
if (calendar.getTime().compareTo(tp2.getStartTime()) == 0) {
// 如果相邻的时间段需要合并,则将第二个时间段的结束时间赋值为第一个时间段的结束时间
tp2.setStartTime(tp1.getStartTime());
list.remove(i);
}
}
// 遍历时间段列表,将与日常工作时间重叠的时间段与日常工作时间合并
for (int i = list.size() - 1; i >= 0; i--) {
TimePeriod tp = list.get(i);
for (TimePeriod dailyTp : dailyList) {
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(dailyTp.getStartTime());
startCalendar.set(Calendar.YEAR, 2021);
startCalendar.set(Calendar.MONTH, 0);
startCalendar.set(Calendar.DAY_OF_MONTH, 1);
startCalendar.set(Calendar.SECOND, 0);
startCalendar.set(Calendar.MILLISECOND, 0);
Date dailyStartTime = startCalendar.getTime();
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(dailyTp.getEndTime());
endCalendar.set(Calendar.YEAR, 2021);
endCalendar.set(Calendar.MONTH, 0);
endCalendar.set(Calendar.DAY_OF_MONTH, 1);
endCalendar.set(Calendar.SECOND, 0);
endCalendar.set(Calendar.MILLISECOND, 0);
Date dailyEndTime = endCalendar.getTime();
if (tp.getStartTime().compareTo(dailyEndTime) < 0 && tp.getEndTime().compareTo(dailyStartTime) > 0) {
// 如果时间段与日常工作时间重叠,则将时间段与日常工作时间合并
if (tp.getStartTime().compareTo(dailyStartTime) < 0) {
tp.setStartTime(dailyTp.getStartTime());
}
if (tp.getEndTime().compareTo(dailyEndTime) > 0) {
tp.setEndTime(dailyTp.getEndTime());
}
}
}
}
}
/**
* 时间段类
*/
private static class TimePeriod {
private Date startTime;
private Date endTime;
public TimePeriod(Date startTime, Date endTime) {
this.startTime = startTime;
this.endTime = endTime;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
}
}
```
您可以调用 `findAvailableTime()` 方法来实现您的需求。其中,`dailyTime` 参数为日常工作时间段字符串,`availableTime` 参数为剩余可用工作时间段字符串,`needTime` 参数为需要的工作时间(分钟)。方法返回值为满足需要工作时间的最早时间段的字符串表示,如果没有满足需要工作时间的时间段,则返回空字符串。