【问题标题】:Sum hours and minutes together Java将小时和分钟相加 Java
【发布时间】:2021-02-03 17:43:33
【问题描述】:

将小时和分钟相加会得出错误的答案。

这里有 2 个带小时的列表。

[[0 小时:0 分钟:0 秒,1 小时:16 分钟:22 秒,0 小时:1 分钟:53 秒,23 小时:54 分钟:18 秒],[0 小时:8 分钟:22秒,0 小时:8 分钟:22 秒,0 小时:8 分钟:22 秒]]这是 HOURS

然后,我将其划分为子列表,分别计算。这是子列表之一。

[0 小时 0 分钟 0 秒 1 小时 16 分钟 22 秒 0 小时 1 分钟 53 秒 23 小时 54 分钟 18 秒]

所以,我得到的这个子列表的答案是:1 小时:12 分钟:33 秒,这是不正确的。我想大约需要 25 小时加上几分钟。

public List<String> getTheHoursWorked() {
    DateTimeFormatter parser = DateTimeFormatter.ofPattern("H 'hours :' m 'mins :' s 'sec'", Locale.US);
    final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
    final Calendar c = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());

    c.clear();
    long startingMS = c.getTimeInMillis();
    int counter = 0;

    for (int k = 0; k < hours.size(); k++){
        List<Object> shorter = new ArrayList<>();
        List<Object> temp;
        temp = (List<Object>) hours.get(k);
        
        long milliseconds = 0;
        for (int m = 0; m < shorter.size(); m++) {
            LocalTime odt = LocalTime.parse((CharSequence) shorter.get(m), parser);
            DateTimeFormatter formatter =
                    DateTimeFormatter.ofPattern("HH:mm:ss");
            String printDate = formatter.format(odt);
            try {
                milliseconds = milliseconds + (dt.parse(printDate).getTime() - startingMS);
                System.out.println(milliseconds + "MILISECONDS");
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        hoursToString.add(String.valueOf(shorter));
        String s = milliseconds / 1000 % 60   + " seconds";
        String m = milliseconds /(60 * 1000) % 60 + " minutes";
        String h = milliseconds / (60 * 60 * 1000) % 24 + " hours";
        String together = h+":"+m+":"+s;
        togetherHours.add(together);
    }
    return togetherHours;
}

【问题讨论】:

  • 欢迎来到 Stack Overflow。请通过tour 了解 Stack Overflow 的工作原理,并阅读How to Ask 以了解如何提高问题的质量。然后edit你的问题包含你的源代码作为minimal reproducible example,它可以被其他人编译和测试。还可以查看help center,看看你可以问什么问题。请参阅:Why is “Can someone help me?” not an actual question?。请看:What Do You Mean “It Doesn't Work”?
  • 您的代码毫无意义。我看不出它是怎么做的。您的内部循环迭代shorter.size() 次,但您将shorter 初始化为一个空列表,然后从不向其中添加任何内容,因此您的整个内部循环将永远不会运行。你的外部循环是关于迭代一个叫做hours的东西,你没有提供它的定义。但这并不重要,因为您只将值分配给temp,然后您永远不会使用tempmilliseconds 似乎总是为零。所以你的代码真的应该什么都不做。
  • 时间处理可能会变得出乎意料的棘手,即使它一开始很简单,所以我建议尽可能使用标准(经过测试和调试)库。不幸的是,Java 时间处理一开始就很糟糕,所以这并不总是最容易做的事情,但仍然可能是最安全的努力学习。在这种情况下,使用 Duration 将解析的时间相加,然后使用标准方法(toHours() 和 toMinutesPart())提取小时和分钟。

标签: java time java-time localtime datetimeformatter


【解决方案1】:

解决的步骤应该是

  1. 0:0 的时间开始
  2. 使用相应的格式化程序解析时间字符串后,迭代列表并分别添加所有小时、分钟和秒。
  3. 如果分钟和/或秒超过 60,请调整小时、分钟和秒。

演示:

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = List.of("0 hours : 0 mins : 0 sec", "1 hours : 16 mins : 22 sec",
                "0 hours : 1 mins : 53 sec", "23 hours : 54 mins : 18 sec");

        // Start with a time of 0:0
        int sumHours = 0;
        int sumMinutes = 0;
        int sumSeconds = 0;

        // Iterate the list and add all hours, minutes and seconds separately after
        // parsing the time strings using the corresponding formatter
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("H' hours : 'm' mins : 's' sec'");
        for (String strTime : list) {
            LocalTime time = LocalTime.parse(strTime, timeFormatter);
            sumHours += time.getHour();
            sumMinutes += time.getMinute();
            sumSeconds += time.getSecond();
        }

        // Adjust hour, minutes and seconds if minute and/or second exceed 60
        sumMinutes += sumSeconds / 60;
        sumSeconds %= 60;
        sumHours += sumMinutes / 60;
        sumMinutes %= 60;

        String strSum = String.format("%d hours : %d mins : %d sec", sumHours, sumMinutes, sumSeconds);
        System.out.println(strSum);
    }
}

输出:

25 hours : 12 mins : 33 sec

【讨论】:

    【解决方案2】:

    解决此问题的一种方法是使用Duration。将每个时间值转换为持续时间,然后将它们相加。提供的时间值显示在两个字符串的数组中。

    String[] hours = {
            "0 hours : 0 mins : 0 sec, 1 hours : 16 mins : 22 sec, 0 hours : 1 mins : 53"
                    + "sec, 23 hours : 54 mins : 18 sec",
            "0 hours : 8 mins : 22 sec, 0 hours : 8"
                    + " mins : 22 sec, 0 hours : 8 mins : 22 sec" };
    

    转换是使用流完成的。该过程在 cmets 中有说明。

    List<Duration> times = Arrays.stream(hours)
            // remove all the spaces in each string
            .map(str -> str.replaceAll("\\s+", ""))
    
            // split each string on the commas.  At this
            // point, each string is processed independently
            // of the other in a separate stream
            .map(str -> Arrays.stream(str.split(","))
                    
                    // parse the time
                    .map(tm -> LocalTime.parse(tm,
                            DateTimeFormatter.ofPattern(
                                    "H'hours':m'mins':s'sec'")))
    
                    // convert each time to a duration
                    .map(lt -> Duration
                            .between(LocalTime.of(0, 0, 0), lt))
    
                    // sum the durations
                    .reduce(Duration.ZERO, (a, b) -> a.plus(b)))
            // and collect in a list
            .collect(Collectors.toList());
    

    此时您可以以标准 Duration 格式打印持续时间。

    times.forEach(System.out::println);
    

    打印

    PT25H12M33S
    PT25M6S
    

    要以更熟悉的格式打印它们,可以使用以下 lambda。

    Function<Duration, String> durationToString = d -> {
        StringBuilder timeString = new StringBuilder();   
        long h = d.toDaysPart()*24+d.toHoursPart();
        timeString.append(h == 1 ? (h + " hour ") : h > 1 ?  (h + " hours ") : "");
        long m = d.toMinutesPart();
        timeString.append(m == 1 ? (m + " minute ") : m > 1 ? (m + " minutes ") : "");
        long s = d.toSecondsPart();
        timeString.append(s == 1 ? (s + " second ") : s > 1 ? (s + " seconds ") : "");
        return timeString.toString();
    };
    

    打印

    25 hours 12 minutes 33 seconds 
    25 minutes 6 seconds 
    

    【讨论】:

      【解决方案3】:
      1. 您的例程中的逻辑错误是 %24,因此您删除了一整天。

      2. 您的代码包含许多无用的部分,例如 temp 并且不干净。

      3. 在循环中构建解析器是一种非常糟糕的风格。

      4. 您做了很多不需要的事情,而使用毫秒和日历是无用的。这是返回预期结果的两个版本。其次是较新的 java 版本。

         public static List<String> getTheHoursWorked() {
         final DateTimeFormatter parser = DateTimeFormatter.ofPattern("H 'hours :' m 'mins :' s 'sec'", Locale.US);
         final List<String> togetherHours = new LinkedList<>();
         for (int k = 0; k < hours.size(); k++){
             final List<String> shorter = hours.get(k);
             long seconds = 0;
             for (int m = 0; m < shorter.size(); m++) {
                 final LocalTime odt = LocalTime.parse(shorter.get(m), parser);
                 seconds += odt.getHour() * 3600 + odt.getMinute() * 60 + odt.getSecond();
             }
             final String s = (seconds       ) % 60 + " seconds";
             final String m = (seconds /   60) % 60 + " minutes";
             final String h = (seconds / 3600)      + " hours";
             final String together = h+":"+m+":"+s;
             togetherHours.add(together);
         }
         return togetherHours;
         }
        
         public static List<String> getTheHoursWorked_new() {
         final DateTimeFormatter parser = DateTimeFormatter.ofPattern("H 'hours :' m 'mins :' s 'sec'", Locale.US);
         final List<String> togetherHours = new LinkedList<>();
         for (final var shorter: hours){
             long seconds = 0;
             for (final var duration : shorter) {
                 final LocalTime odt = LocalTime.parse(duration, parser);
                 seconds += odt.getHour() * 3600 + odt.getMinute() * 60 + odt.getSecond();
             }
             final String s = (seconds       ) % 60 + " seconds";
             final String m = (seconds /   60) % 60 + " minutes";
             final String h = (seconds / 3600)      + " hours";
             final String together = h+":"+m+":"+s;
             togetherHours.add(together);
         }
         return togetherHours;
         }
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-28
        • 1970-01-01
        • 2018-04-23
        • 1970-01-01
        • 1970-01-01
        • 2015-07-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多