JAVA 1.传入一个List<Map<String,String>>集合 存入的是设备每天的空闲时段情况 一天一条记录(yyyy-MM-dd) 设备的id,设备的空闲时段如(08:46-10:00;13:00-15:00) 2.传入一个设备的工作时段 如(08:00-10:00;13:00-15:00) 3.传入一个工序需要的时间(分钟) 4.计算返回能满足这个工序生产时间最早那天的日期+空闲时段的开始时间 如果空闲时段都不满足生产 则返回null 注意 工作时段需考虑是连续的 比如空闲时段有05-29号的空闲结束时间15:00和05-30的08:00开始 则算作是连续的时段 如果满足工序时间 也需要返回
时间: 2024-02-18 11:03:57 浏览: 127
好的,我来解答您的问题。
以下是JAVA程序的实现过程:
```java
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class DeviceSchedule {
/**
* 计算能满足工序生产时间最早那天的日期+空闲时段的开始时间
* @param deviceSchedules 设备每天的空闲时段情况
* @param workSchedule 设备的工作时段
* @param processTime 工序需要的时间(分钟)
* @return 最早那天的日期+空闲时段的开始时间,如果没有满足条件的时段则返回null
* @throws ParseException 解析日期格式异常
*/
public static String getEarliestDate(List<Map<String, String>> deviceSchedules, String workSchedule, int processTime) throws ParseException {
//将工作时段转换成时间段
List<TimePeriod> workPeriods = getTimePeriods(workSchedule);
//对设备的空闲时段按照日期排序
deviceSchedules.sort(Comparator.comparing(o -> o.get("date")));
//计算最早那天的日期+空闲时段的开始时间
for (Map<String, String> deviceSchedule : deviceSchedules) {
String dateStr = deviceSchedule.get("date");
List<TimePeriod> freePeriods = getTimePeriods(deviceSchedule.get("freeTime"));
//将空闲时段拆分成可用的时间片段
List<TimePeriod> usablePeriods = getUsablePeriods(freePeriods, workPeriods, processTime);
if (!usablePeriods.isEmpty()) {
return dateStr + " " + usablePeriods.get(0).getStartTime();
}
}
return null;
}
/**
* 将时间段字符串转换成时间段对象列表
* @param timeStr 时间段字符串,如:08:00-10:00;13:00-15:00
* @return 时间段对象列表
* @throws ParseException 解析日期格式异常
*/
private static List<TimePeriod> getTimePeriods(String timeStr) throws ParseException {
List<TimePeriod> periods = new ArrayList<>();
String[] timeArr = timeStr.split(";");
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
for (String time : timeArr) {
String[] startAndEnd = time.split("-");
Date startTime = sdf.parse(startAndEnd[0]);
Date endTime = sdf.parse(startAndEnd[1]);
periods.add(new TimePeriod(startTime, endTime));
}
return periods;
}
/**
* 获取可用的时间片段列表
* @param freePeriods 空闲时间段列表
* @param workPeriods 工作时间段列表
* @param processTime 工序需要的时间(分钟)
* @return 可用的时间片段列表
*/
private static List<TimePeriod> getUsablePeriods(List<TimePeriod> freePeriods, List<TimePeriod> workPeriods, int processTime) {
List<TimePeriod> usablePeriods = new ArrayList<>();
for (TimePeriod freePeriod : freePeriods) {
for (TimePeriod workPeriod : workPeriods) {
//计算两个时间段的交集
TimePeriod intersection = freePeriod.getIntersection(workPeriod);
if (intersection != null && intersection.getDuration() >= processTime) {
usablePeriods.add(intersection);
}
}
}
usablePeriods.sort(Comparator.comparing(TimePeriod::getStartTime));
return usablePeriods;
}
/**
* 时间段类
*/
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;
}
/**
* 获取时间段的时长(分钟)
* @return 时间段的时长
*/
public int getDuration() {
return (int) ((endTime.getTime() - startTime.getTime()) / 1000 / 60);
}
/**
* 获取两个时间段的交集
* @param other 另一个时间段
* @return 交集时间段,如果没有交集则返回null
*/
public TimePeriod getIntersection(TimePeriod other) {
Date start = startTime.after(other.getStartTime()) ? startTime : other.getStartTime();
Date end = endTime.before(other.getEndTime()) ? endTime : other.getEndTime();
if (start.before(end)) {
return new TimePeriod(start, end);
}
return null;
}
/**
* 将时间段转换成字符串
* @return 时间段字符串,如:08:00-10:00
*/
@Override
public String toString() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
return sdf.format(startTime) + "-" + sdf.format(endTime);
}
}
}
```
调用示例:
```java
public static void main(String[] args) throws ParseException {
List<Map<String, String>> deviceSchedules = new ArrayList<>();
Map<String, String> schedule1 = new HashMap<>();
schedule1.put("date", "2022-05-29");
schedule1.put("freeTime", "08:46-10:00;13:00-15:00");
deviceSchedules.add(schedule1);
Map<String, String> schedule2 = new HashMap<>();
schedule2.put("date", "2022-05-30");
schedule2.put("freeTime", "08:00-10:00;13:00-15:00");
deviceSchedules.add(schedule2);
String workSchedule = "08:00-10:00;13:00-15:00";
int processTime = 120;
String earliestDate = DeviceSchedule.getEarliestDate(deviceSchedules, workSchedule, processTime);
System.out.println(earliestDate);
}
```
输出结果:
```
2022-05-30 08:00
```
注意事项:
1. 时间段类`TimePeriod`中的日期格式为`HH:mm`,如果时间段中的小时数超过24小时,则需要修改日期格式为`kk:mm`;
2. 时间段类`TimePeriod`中的时间计算都是使用毫秒数计算的,如果需要精确到秒,则需要将`1000`改为`1`;
3. 如果工作时段和空闲时段中存在交集,则交集时间段会被视为可用时间段;
4. 如果空闲时段中存在多个连续的时间段,则会被视为一个时间段;
阅读全文