我编写了一个类,它能够表示系统的截止时间(正常运行时间或停机时间)。
问题中用例的难点在于结束时间在开始时间之前。这意味着停机时间从一周中的某一天开始,并在某个时间结束第二天。
所以周一到周五,从 18:00 到 07:00,意味着系统也在周六,午夜到 7:00 关闭。如果我们想正确处理这个问题,我们需要考虑到这一点。
类的源代码下方。构造函数接受Set,其中包含截止时间开始的星期几,以及开始和结束时间。
public class Uptime {
private final Set<DayOfWeek> daysOfUptimeStart;
private final LocalTime startTime;
private final LocalTime endTime;
public Uptime(Set<DayOfWeek> daysOfUptimeStart, LocalTime startTime, LocalTime endTime) {
this.daysOfUptimeStart = Collections.unmodifiableSet(daysOfUptimeStart);
this.startTime = startTime;
this.endTime = endTime;
}
public boolean isUp(LocalDateTime dateTime) {
LocalTime time = dateTime.toLocalTime();
if (!this.startTime.isAfter(this.endTime)) {
return this.daysOfUptimeStart.contains(dateTime.getDayOfWeek()) && !time.isBefore(this.startTime) && !time.isAfter(this.endTime);
}
else {
if (time.isBefore(this.startTime) && time.isAfter(this.endTime)) {
return false;
}
else {
return this.daysOfUptimeStart.contains(dateTime.getDayOfWeek().minus(!time.isBefore(this.startTime) ? 0 : 1));
}
}
}
}
测试
为了对此进行测试,我生成了一些日期:2020 年 9 月 14 日至 20 日(周一至周日)的所有日期,加上凌晨 4 点、上午 8 点、下午 1 点、下午 5 点、晚上 7 点和晚上 11 点。
代码打印日期时间,以及系统是否启动。我们期望:
- 周一晚上 7 点和 11 点系统停机;
- 周二至周五,系统在凌晨 4 点、晚上 7 点和晚上 11 点关闭;
- 周六凌晨 4 点系统停机。
// Static importing java.time.DayOfWeek.* here
Uptime uptime = new Uptime(Set.of(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY), LocalTime.of(18, 0), LocalTime.of(7, 0));
YearMonth ym = YearMonth.of(2020, Month.SEPTEMBER);
List<LocalDateTime> datetimes = IntStream.rangeClosed(14, 20) // September 2020, MONDAY till SUNDAY
.mapToObj(ym::atDay)
.flatMap(date -> IntStream.of(4, 8, 13, 17, 19, 23)
.mapToObj(hour -> LocalTime.of(hour, 0))
.map(date::atTime))
.collect(Collectors.toList());
datetimes.forEach(datetime -> System.out.printf("%s %-12s %s\n", datetime, "(" + datetime.getDayOfWeek() + "):", !uptime.isUp(datetime)));
输出符合预期。
更新
对原始帖子的修订略微改变了要求。然而,
您不必修改上述代码,因为如果您修改您的输入,它仍然可以工作。事实上,您记录的是正常运行时间,而不是停机时间。因此,请注册您的正常运行时间:周一至周五,7:00 至 18:00。
Set<DayOfWeek> daysOfWeek = Set.of(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY);
LocalTime start = LocalTime.of(7, 0);
LocalTime end = LocalTime.of(18, 0);
Uptime uptime = new Uptime(daysOfWeek, start, end);
现在使用uptime.isUp(LocalDateTime.now()),您仍然可以检查系统是否已启动。