【问题标题】:Average of two LocalTimes两个本地时间的平均值
【发布时间】:2018-11-30 15:01:04
【问题描述】:

如何获得两个LocalTimes 的平均值?找不到任何合适的方法。

例如 08:00 和 14:30,应该返回 (14-8)/2 = 3 + 分钟 (30-00= 30)/2,所以 3:15 然后像

Localtime xxx = LocalTime.parse("08:00", formatter).plus(3, ChronoUnit.HOURS); 
//and after that's done
xxx = xxx.plus(15, ChronoUnit.MINUTES);

现在假设我有以下代码:

   //this means that if code is 08:00, it should look whether the average of Strings split21 and split2 (which are put in time2 and time3, where time2 is ALWAYS before time3) is before 08:00
   if(code1.contains("800")) {

        LocalTime time1 = LocalTime.parse("08:00", formatter);
        LocalTime time2 = LocalTime.parse(split21, formatter);
        LocalTime time3 = LocalTime.parse(split2, formatter);
        LocalTime average = 
        if(time2.isBefore(time1)) {
            return true;
        }
        else {
            return false;
        }
    }

显然我可以使用 .getHour 和 .getMinute ,但是这里有两个问题。

  1. 我不能划分 LocalTime(仅当分别处理小时和分钟时,但老实说这有点太中世纪了
  2. 如果我不直接划分小时和分钟,它将高于 24:00,我不知道会发生什么:我想它会在 00:00 等而不是 36:00 时更进一步示例。

是否有人可以完成此代码/解释问题所在?

【问题讨论】:

  • 为什么在(14-8)/2 中减号,在(00+30 = 30)/2 中加号我不明白!
  • 这实际上是一个好问题,抱歉我写得很快。我的意思是(30-00)
  • 两次的平均值是多少? 8:0014:30 的平均值是多少 3:15?我假设它是11:15。还是您需要差异?那将是6:30
  • 我没有说平均是 3:15。您必须在第一次上加上 3:15 才能得到平均值。快速数学

标签: java date localtime


【解决方案1】:

由于LocalTime 有效地定义为自午夜以来的纳秒,您可以执行以下操作:

public static LocalTime average(LocalTime t1, LocalTime... others) {
  long nanosSum = t1.toNanoOfDay();
  for (LocalTime other : others) {
    nanoSum += others.toNanoOfDay();
  }
  return LocalTime.ofNanoOfDay(nanoSum / (1+others.length));
}

【讨论】:

  • 好答案。这应该是公认的答案。
【解决方案2】:

我想你的问题的方式是你想要两次之间的中点。以这种方式思考,我发现取时间之间的差异,除以 2 并添加到第一次(或从第二次减去)是最自然的。这似乎也是您在问题中尝试过的。与其自己处理小时和分钟,不如使用Duration 类:

    LocalTime time1 = LocalTime.of(8, 0);
    LocalTime time2 = LocalTime.of(14, 30);
    Duration diff = Duration.between(time1, time2);
    LocalTime midpoint = time1.plus(diff.dividedBy(2));
    System.out.println(midpoint);

输出:

11:15

显然它只能使用两次,而不是三次或更多。两次以上的情况在其他几个答案中得到了很好的处理。

【讨论】:

    【解决方案3】:

    您可以使用 Java 8 java.time 包,使用 LocalTime.ofSecondOfDay(long) 方法轻松地做到这一点。这实际上是一天中的小时和分钟(以及秒)的总和。

    public static LocalTime average(LocalTime... times) {
        return LocalTime.ofSecondOfDay((long) Arrays.stream(times)
            .mapToInt(LocalTime::toSecondOfDay)
            .average()
            .getAsDouble());
    }
    
    LocalTime t1 = LocalTime.of(8, 0);
    LocalTime t2 = LocalTime.of(14, 30);
    System.out.println(average(t1, t2)); // Prints 11:15
    

    【讨论】:

    • 提示:使用other Answer 中看到的纳秒,避免Double
    【解决方案4】:

    我认为你的意思是这样的:

    public static LocalTime average(LocalTime time1, LocalTime time2) {
        if (time1.isAfter(time2)) {
            return LocalTime.of(
                    time1.plusHours(time2.getHour()).getHour() / 2,
                    time1.plusMinutes(time2.getMinute()).getMinute() / 2
            );
        } else {
            return LocalTime.of(
                    time2.plusHours(time1.getHour()).getHour() / 2,
                    time2.plusMinutes(time1.getMinute()).getMinute() / 2
            );
        }
    }
    

    然后你可以多次调用你的方法:

    LocalTime time1 = LocalTime.of(14, 30);
    LocalTime time2 = LocalTime.of(8, 00);
    
    LocalTime result = average(time1, time2);
    

    以3次为例:

    LocalTime time1 = LocalTime.of(14, 30);
    LocalTime time2 = LocalTime.of(8, 00);
    LocalTime time3 = LocalTime.now();
    
    LocalTime result = average(average(time1, time2), time3);
    

    ..等等

    第一个例子的输出

    11:15
    

    【讨论】:

    • 如果 time2 则没有安全性
    • 你的意思是@ArnaultLePrévost-Corvellec 是哪个安全性?你检查第一个例子的结果了吗?
    • 对于平均值:在您的功能中,average(time1,time2) == average(time2,time1) 不是
    • 如果你运行 System.out.println(average(time2, time1).format(DateTimeFormatter.ISO_LOCAL_TIME)); System.out.println(平均(time1, time2).format(DateTimeFormatter.ISO_LOCAL_TIME));结果是 03:15:00 09:15:00
    • 本地时间平均值 = (time2.plusHours(result.getHour()).plusMinutes(result.getMinute()));这对平均值是否正确?结果来自您的代码
    【解决方案5】:

    考虑到您在代码中的评论,我提出了此代码 //(分别放在time2和time3中,其中time2总是在time3之前)

    DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_TIME;
    
        LocalTime time1 = LocalTime.parse("08:00", formatter);
        LocalTime time2 = LocalTime.parse("14:30", formatter);
    
        int hour1 = time1.get(ChronoField.CLOCK_HOUR_OF_DAY);
        int hour2 = time2.get(ChronoField.CLOCK_HOUR_OF_DAY);
    
        int min1 = time1.get(ChronoField.MINUTE_OF_HOUR);
        int min2 = time2.get(ChronoField.MINUTE_OF_HOUR);
    
        int avgHour = (hour2-hour1)/2;
        int avgMin = (min2-min1)/2;
    
        String newavgHour = "00:00";
        if(String.valueOf(avgHour).length() == 1) {
            newavgHour = "0"+avgHour+":00";
        } else {
            newavgHour = avgHour+":00";
        }
    
        LocalTime avgTime = LocalTime.parse(newavgHour, formatter).plus(avgMin, ChronoUnit.MINUTES);
        System.out.println(avgTime);
    

    【讨论】:

    • 这是一个非常糟糕的代码 LOL 一定会喜欢它,我不是为了得到这样的回应,因为我自己也能做到这一点。
    • 我用09:4514:30 尝试了你的代码。预计平均时间:12:07:30。实际输出:01:53。
    猜你喜欢
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多