问题的关键在于
LocalTime
仅表示午夜零点到中午十二点之间的时间范围,没有超出这些范围的概念。
你真正需要的是与时间值相关联的日期值,这将允许你计算超过24小时的持续时间。
如果做不到这一点,你就需要自己“捏造”数值。这意味着,当下一个时间小于上一个时间时,你需要手动添加一个额外的周期,比如一天。
可能有几种方法可以做到这一点,这只是其中一种方法。
它需要一个设置为当前日期的
ZonedDateTime
作为“锚点”日期。然后将每个日程的
Time
应用于此日期。当它检测到最后一个到达时间早于下一个离开时间时,就会将一天添加到数值中。
import java.time.Duration;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HHmm");
List<Schedule> route = new ArrayList<>(4);
route.add(new Schedule(LocalTime.parse("1139", formatter), LocalTime.parse("1435", formatter)));
route.add(new Schedule(LocalTime.parse("0906", formatter), LocalTime.parse("1937", formatter)));
route.add(new Schedule(LocalTime.parse("0804", formatter), LocalTime.parse("1521", formatter)));
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime lastArrival = null;
Duration totalDuration = Duration.ZERO;
for (Schedule schedule : route) {
ZonedDateTime depart = zdt.with(schedule.getDepart());
ZonedDateTime arrive = zdt.with(schedule.getArrive());
if (lastArrival != null) {
if (lastArrival.isAfter(depart)) {
zdt = zdt.plusDays(1);
depart = depart.plusDays(1);
arrive = arrive.plusDays(1);
}
Duration duration = Duration.between(lastArrival, depart);
totalDuration = totalDuration.plus(duration);
System.out.println("...Wait for " + duration.toHoursPart() + "h " + duration.toMinutesPart() + "m");
}
Duration duration = Duration.between(depart, arrive);
System.out.println(duration.toHoursPart() + "h " + duration.toMinutesPart() + "m");
totalDuration = totalDuration.plus(duration);
lastArrival = arrive;
}
System.out.println("Total duration of " + totalDuration.toHoursPart() + "d " + totalDuration.toHoursPart() + "h " + totalDuration.toMinutesPart() + "m");
}
public static class Schedule {
private LocalTime depart;
private LocalTime arrive;
public Schedule(LocalTime depart, LocalTime arrive) {
this.depart = depart;
this.arrive = arrive;
}
public LocalTime getDepart() {
return depart;
}
public LocalTime getArrive() {
return arrive;
}
}
}
这将输出...
2h 56m
...Wait for 18h 31m
10h 31m
...Wait for 12h 27m
7h 17m
Total duration of 3d 3h 42m
但是为什么要这样做呢?因为日期/时间处理非常混乱,有闰秒、年份和其他愚蠢的规则,旨在防止它崩溃成混乱状态(这就是为什么没有航班在12:00
:/)...而且不要让我开始谈夏令时...
Java日期/时间API为我们处理了所有这些问题。
我选择在单个工作单元中维护日期/时间信息,即UTC,这允许所有值具有某种有用的含义。您也可以轻松使用不同的锚定时间以及转换为不同的时区以供演示使用 - 因此,您可以在目标地显示本地时间,但计算将继续根据一个真实的参考点进行。
LocalDateTime
,它允许从一天过渡到另一天。 - MadProgrammerZonedDateTime
,因为您可能会在不同的时区之间传递,从而使计算变得相当奇怪:P(不是没有听说过在离开之前到达) - MadProgrammer