两次之间的LocalTime()差

时间:2018-11-12 00:02:57

标签: java localtime time-format

我有一个航班行程计划,需要获取出发时间和到达时间之间的差额。我从数据中获得这些指定的时间作为String。这是我的问题:

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

第一次返回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航班。上面输出的格式为(城市,出发时间,航班号,目的地,到达时间)。

2 个答案:

答案 0 :(得分:5)

24小时内的总分钟数为1440。因此,当差异小于零(但您需要一个正数)时,应在结果中加一整天:

int diff = MINUTES.between(arrival, a);
if (diff < 0) {
    diff += 1440;
}

您可以使用以下方法实现相同的目的:

int diff = (MINUTES.between(arrival, a) + 1440) % 1440;

答案 1 :(得分:3)

眼前的主要问题是LocalTime仅代表了午夜AM到午夜PM之间的时间表示,没有任何超出这些范围的概念。

您真正需要的是一个与时间值关联的日期值,这将使您可以计算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

但是为什么要这样做?因为日期/时间操纵是一团糟,所以具有leap秒,年份和其他愚蠢的规则,这些规则可以阻止它陷入混乱之中(这就是12:00:/上没有飞行的原因)。 ,不要让我开始使用夏令时...

Java日期/时间API为我们解决了所有这些问题。

我选择将日期/时间信息保存在单个工作单元(即UTC)中,该单元允许所有值具有某种有用的含义。您可以轻松地使用不同的锚点时间,也可以转换为其他时区以进行演示-这样您就可以在目的地显示本地时间,但是计算将继续针对单个真点进行。