James Ferry
James Ferry

Reputation: 137

Sum of time duration's from a list in android studio

I am trying to calculate the sum of a list of time duration for an attendance app. I was able to calculate the difference of 2 times but not sure how to traverse through the list to add the dates together.

The below code is what I have attempted so far. There are 2 time durations in the list and they are added to the list from Firebase using an object class.

Duration 1 = 0:5:42
Duration 2 = 0:0:09
Expected Total = 0:5:51

//initialized

long sum;

//current method attempted

public void grandTotal() throws ParseException {
        java.util.Date date1;
        java.util.Date date2;

        DateFormat formatter = new SimpleDateFormat("hh:mm:ss");
        for(int i = 0 ; i < newList.size(); i++) {
            String str_time1 = newList.get(i).getDuration();
            date1 = formatter.parse(str_time1);

            for (int j = 1; j < newList.size(); j++) {
                String str_time2 = newList.get(j).getDuration();
                date2 = formatter.parse(str_time2);
                sum = date1.getTime() + date2.getTime();
            }
        }
        secs = sum/1000;

        mins = secs/60;
        secs%=60;
        hours = mins/60;
        mins%=60;
        txtDailyBalance.setText(hours+":"+mins+":"+String.format("%02d",secs));
    }

Result output I get is = -1:59:42

I got the solution using this method but I don't think this is good practice so I have been looking into learning more about the different methods in this post so thank you.

//Sum of time durations for that day
public void grandTotal() throws ParseException {
    java.util.Date date1;
    java.util.Date date2;

    DateFormat formatter = new SimpleDateFormat("hh:mm:ss");
    for(int i = 0 ; i < newList.size(); i++) {
        timeDuration.add(newList.get(i).getDuration());
    }
    long tDur = 0;
    for (String tmp : timeDuration){
        String[] arr = tmp.split(":");
        tDur += Integer.parseInt(arr[2]);
        tDur += 60 * Integer.parseInt(arr[1]);
        tDur += 3600 * Integer.parseInt(arr[0]);
    }
    long hours = tDur / 3600;
    tDur %= 3600;
    long mins = tDur / 60;
    tDur %= 60;
    long secs = tDur;
    txtDailyBalance.setText(hours+":"+mins+":"+String.format("%02d",secs));
}

Upvotes: 2

Views: 6720

Answers (2)

Meno Hochschild
Meno Hochschild

Reputation: 44071

If you don't insist on having a customized format but just look for an easier way to add duration objects then Oles answer might be okay for you. However, ThreetenABP lacks a duration formatter.

But if you want to avoid writing auxiliary methods for formatting and parsing durations in the format "hh:mm:ss" (and are willing to add a 3rd-party-dependency) then you might try my lib Time4A and use a pattern-based approach:

Duration.Formatter<ClockUnit> parser = Duration.formatter(ClockUnit.class, "#h:#m:ss");
String[] durations = { "0:5:42", "0:0:09" };
Duration<ClockUnit> d = Duration.ofZero();

for (String duration : durations) {
    d = d.plus(parser.parse(duration));
}

d = d.with(Duration.STD_CLOCK_PERIOD); // normalization
Duration.Formatter<ClockUnit> printer = Duration.formatter(ClockUnit.class, "hh:mm:ss");
System.out.println(printer.format(d)); // 00:05:51

Upvotes: 1

Anonymous
Anonymous

Reputation: 86324

As I have said in the comments, use the Duration class for durations:

    List<Duration> durations = List.of(
            Duration.ofMinutes(5).plusSeconds(42), // 0:05:42
            Duration.ofSeconds(9),                 // 0:00:09
            Duration.parse("PT11M"));              // 0:11:00

    Duration sum = Duration.ZERO;
    for (Duration dur : durations) {
        sum = sum.plus(dur);
    }

    System.out.println(sum);

This prints

PT16M51S

So 16 minutes 51 seconds.

Durations parse and produce ISO 8601 format natively, it goes like what you just saw, PT16M51S. If you need to have your duration strings in hh:mm:ss format, I am sure you can write auxiliary methods for formatting and parsing that format. For formatting there are already a couple of questions on Stack Overflow, for example How to format a duration in java? (e.g format H:MM:SS) (search for more).

Why not Date?

Using a Date for a duration is incorrect. A point in time and an amount of time are two different concepts. The error you saw may be due to time zone offset, but you risk other errors along the way, and worse, your code is difficult to read and easy to misunderstand.

Also the Date class is long outdated and replaced by classes in java.time, the modern Java date and time API. The same API introduces the classes Period (for years, months and days) and Duration (for hours, minutes, seconds and fraction of second).

Question: Can I use java.time on Android?

Yes, you can use java.time on Android. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices the modern API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
  • On older Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Upvotes: 5

Related Questions