java - 比较多个日历并使用开始和结束查找哪个更接近运行或现在处于活动状态
问题描述
我的求助请求有点奇怪。我会尽量简短。
我有这条线,我在其中解析 Ex 的时间表。18:00-19:00;22:00-23:00 18:00-19:00 为一个对象,22:00-23:00 以“;”隔开。这意味着您可以添加无限的时间表。
现在我使用以下方法解析这一行:
Arrays.asList(schedule.replaceAll("\\s", "").split(";")).forEach(s -> _schedules.add(new ScheduleCalendar(Integer.parseInt(s.split("-")[0].split(":")[0]), Integer.parseInt(s.split("-")[0].split(":")[1]), Integer.parseInt(s.split("-")[1].split(":")[0]), Integer.parseInt(s.split("-")[1].split(":")[1]))));
我用这个类
public static class ScheduleCalendar
{
private final Calendar[] _calendar = new Calendar[2];
public ScheduleCalendar(final int startingHour, final int startingMinute, final int endingHour, final int endingMinute)
{
final Calendar starting = Calendar.getInstance();
starting.set(Calendar.HOUR_OF_DAY, startingHour);
starting.set(Calendar.MINUTE, startingMinute);
starting.set(Calendar.SECOND, 0);
starting.set(Calendar.MILLISECOND, 0);
_calendar[0] = starting;
final Calendar ending = Calendar.getInstance();
ending.set(Calendar.HOUR_OF_DAY, endingHour);
ending.set(Calendar.MINUTE, endingMinute);
ending.set(Calendar.SECOND, 0);
ending.set(Calendar.MILLISECOND, 0);
_calendar[1] = ending;
}
public boolean isBefore(final ScheduleCalendar schedule)
{
return false;
}
public Calendar[] getCalendars()
{
return _calendar;
}
public boolean isNow()
{
return _calendar[0].getTimeInMillis() > System.currentTimeMillis() && _calendar[1].getTimeInMillis() < System.currentTimeMillis();
}
}
最后存储在
private final List<ScheduleCalendar> _schedules = new ArrayList<>();
现在我想做一个方法来检索最近的时间表或如果可能的话。有没有什么花哨和快速的方法使用 java 8-16 来重现这段代码而不必编写这么长的代码?有什么图书馆可能吗?
解决方案
如果我们使用的是 java 8+ ,则没有充分的理由使用Calendar
假设时间范围'from' < 'to',即“23:00-01:00”是不允许的,使用LocalTime
with lambda函数可以大大简化代码。
寻找最近或活动的算法:
- 丢弃过时的时间范围('from' > active time)
- 对于那些“到”<活动时间,选择最大“到”(最接近)的
- 如果(2)中没有时间范围,对于那些'from' < active time <'to',选择最大'from'的那个。
当然,您可以交换 2 和 3 的顺序,具体取决于您对最近与活动的优先级。
import java.time.LocalTime;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class Scheduler {
public static void main(String[] args) {
String values = "21:00-23:00;20:00-21:00;18:00-19:00;22:30-23:00";
LocalTime now = LocalTime.parse("22:00");
List<LocalTimeRange> timeRanges = Arrays.stream(values.split(";")).map(s -> {
String[] arr = s.split("-");
return new LocalTimeRange(LocalTime.parse(arr[0]), LocalTime.parse(arr[1]));
}).collect(Collectors.toList());
getClosetOrActive(timeRanges, now).ifPresentOrElse(System.out::println, () -> System.out.println("No time range match"));
}
private static Optional<LocalTimeRange> getClosetOrActive(List<LocalTimeRange> timeRanges, LocalTime activeTime) {
// Outdated range is discarded
List<LocalTimeRange> notOutdatedRanges = timeRanges.stream().
filter(timeRange -> !timeRange.getFrom().isAfter(activeTime)).collect(Collectors.toList());
// For range before active time, retrieve the one with 'to' closest to activeTime
Optional<LocalTimeRange> closet = notOutdatedRanges.stream().filter(localTimeRange -> localTimeRange.getTo().isBefore(activeTime))
.sorted(Comparator.comparing(LocalTimeRange::getTo).reversed()).findFirst();
if (closet.isPresent()) {
return closet;
}
// For range cover active time, retrieve the one with latest 'from'
return notOutdatedRanges.stream().filter(localTimeRange -> !localTimeRange.getTo().isBefore(activeTime))
.sorted(Comparator.comparing(LocalTimeRange::getFrom).reversed()).findFirst();
}
public static class LocalTimeRange {
private final LocalTime from;
private final LocalTime to;
public LocalTime getFrom() {
return from;
}
public LocalTime getTo() {
return to;
}
@Override
public String toString() {
return from + "-" + to;
}
public LocalTimeRange(LocalTime from, LocalTime to) {
this.from = from;
this.to = to;
}
}
}
推荐阅读
- python - 如何访问 csv。日期修改值
- asp.net-core - 如何在等待的情况下获得回报以及返回值
- javascript - 将 div 列表中的数字添加到总 div
- c# - 布尔值 IsWallSliding 不断转为真假
- statistics - h(simpleError(msg, call)) 中的错误:在为函数“summary”选择方法时评估参数“object”时出错
- python - 使用 Pillow 中的裁剪方法,并将图像作为参数传递给函数
- python - 将列表列表作为蛇形通配符运行
- c# - 无法弄清楚如何使用 C# pcsc 将数据写入 NFC 类型 4 标签
- javascript - 如何将图像设置为画布背景而不是让它在 Android Studio/JavaScript 中填充颜色
- django - 仅当在 Django 中删除最后一个 FK 关系时,如何级联删除?