Основная проблема под рукой - 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)));
// Anchor time...
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)) {
// Most likely, we've shifted to a new day...
// Updat the anchor and target values
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
: /) ... и не заводите меня на летнее время ...
API даты / времени Java позаботится обо всем этом для нас.
Я решил сохранить информацию о дате / времени в одной единице работы, то есть в формате UTC, что позволяет всем значениям иметь какое-то полезное значение. Вы можете легко использовать другое время привязки, а также конвертировать в другой часовой пояс для использования в презентации - чтобы вы могли отображать время по местному времени в месте назначения, но вычисления по-прежнему будут выполняться с единой точкой правды.