LocalTime() 两次之间的差异
LocalTime() difference between two times
我有一个航班行程计划,我需要在其中获取出发时间和到达时间之间的差异。我从数据中获取这些指定时间作为字符串。这是我的问题:
import static java.time.temporal.ChronoUnit.MINUTES;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class test2 {
public static void main(String[] args) {
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("HHmm");
LocalTime departure = LocalTime.parse("1139", dateFormat);
LocalTime arrival = LocalTime.parse("1435", dateFormat);
LocalTime a = LocalTime.parse("0906", dateFormat);
System.out.println(MINUTES.between(departure, arrival));
System.out.println(MINUTES.between(arrival, a));
}
}
输出:
176
-329
第一次returns区别11:39和14:35就好了。但是第二个差异只有 5 个小时,而应该是 19 个小时。我该如何解决这个问题,我做错了什么?
如有任何帮助,我们将不胜感激。
编辑:我正在使用图表来存储我的数据。两个机场之间的最短路线示例如下:
Route for Edinburgh to Sydney
1 Edinburgh, 1139, TK3245, Istanbul, 1435
2 Istanbul, 0906, TK4557, Singapore, 1937
3 Singapore, 0804, QF1721, Sydney, 1521
这些是我们从 EDI 到 SYD 的 3 个航班。上面输出的格式是(城市,出发时间,航班号,目的地,到达时间)。
24 小时的总分钟数是 1440 分钟。所以当差异小于零时(但你需要一个正数)那么你应该在结果中加上一整天:
int diff = MINUTES.between(arrival, a);
if (diff < 0) {
diff += 1440;
}
你可以用这个来达到同样的目的:
int diff = (MINUTES.between(arrival, a) + 1440) % 1440;
手头的主要问题是 LocalTime
只是表示午夜 AM 到午夜 PM 之间的时间,它没有超出这些界限的任何范围的概念。
您真正需要的是一个与时间值关联的日期值,这样您就可以计算超过 24 小时的持续时间。
否则,您将需要 "fudge" 自己设置这些值。这意味着,当下一个时间小于上一个时间时,您将需要手动添加一个额外的时间段,也许是一天。
可能有几种方法可以做到这一点,这只是其中一种。
它将 ZonedDateTime
(设置为当前日期)用作 "anchor" 日期。然后将计划的每个 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
但是为什么要这样做呢?因为 date/time 操作完全是一团糟,有闰秒、年份和其他愚蠢的规则,这些规则旨在阻止它全部崩溃(这就是为什么 12:00
没有航班的原因:/) ...并且不要让我开始夏令时...
Javadate/timeAPI为我们处理了这一切。
我选择在单个工作单元(即 UTC)中维护 date/time 信息,它允许所有值都具有某种有用的含义。您可以轻松地使用不同的锚点时间以及转换为不同的时区以用于演示 - 因此您可以在目的地显示当地时间的时间,但计算将继续针对单一事实进行。
我有一个航班行程计划,我需要在其中获取出发时间和到达时间之间的差异。我从数据中获取这些指定时间作为字符串。这是我的问题:
import static java.time.temporal.ChronoUnit.MINUTES;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class test2 {
public static void main(String[] args) {
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("HHmm");
LocalTime departure = LocalTime.parse("1139", dateFormat);
LocalTime arrival = LocalTime.parse("1435", dateFormat);
LocalTime a = LocalTime.parse("0906", dateFormat);
System.out.println(MINUTES.between(departure, arrival));
System.out.println(MINUTES.between(arrival, a));
}
}
输出:
176
-329
第一次returns区别11:39和14:35就好了。但是第二个差异只有 5 个小时,而应该是 19 个小时。我该如何解决这个问题,我做错了什么?
如有任何帮助,我们将不胜感激。
编辑:我正在使用图表来存储我的数据。两个机场之间的最短路线示例如下:
Route for Edinburgh to Sydney
1 Edinburgh, 1139, TK3245, Istanbul, 1435
2 Istanbul, 0906, TK4557, Singapore, 1937
3 Singapore, 0804, QF1721, Sydney, 1521
这些是我们从 EDI 到 SYD 的 3 个航班。上面输出的格式是(城市,出发时间,航班号,目的地,到达时间)。
24 小时的总分钟数是 1440 分钟。所以当差异小于零时(但你需要一个正数)那么你应该在结果中加上一整天:
int diff = MINUTES.between(arrival, a);
if (diff < 0) {
diff += 1440;
}
你可以用这个来达到同样的目的:
int diff = (MINUTES.between(arrival, a) + 1440) % 1440;
手头的主要问题是 LocalTime
只是表示午夜 AM 到午夜 PM 之间的时间,它没有超出这些界限的任何范围的概念。
您真正需要的是一个与时间值关联的日期值,这样您就可以计算超过 24 小时的持续时间。
否则,您将需要 "fudge" 自己设置这些值。这意味着,当下一个时间小于上一个时间时,您将需要手动添加一个额外的时间段,也许是一天。
可能有几种方法可以做到这一点,这只是其中一种。
它将 ZonedDateTime
(设置为当前日期)用作 "anchor" 日期。然后将计划的每个 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
但是为什么要这样做呢?因为 date/time 操作完全是一团糟,有闰秒、年份和其他愚蠢的规则,这些规则旨在阻止它全部崩溃(这就是为什么 12:00
没有航班的原因:/) ...并且不要让我开始夏令时...
Javadate/timeAPI为我们处理了这一切。
我选择在单个工作单元(即 UTC)中维护 date/time 信息,它允许所有值都具有某种有用的含义。您可以轻松地使用不同的锚点时间以及转换为不同的时区以用于演示 - 因此您可以在目的地显示当地时间的时间,但计算将继续针对单一事实进行。