Reputation: 137
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
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
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).
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).
Yes, you can use java.time
on Android. It just requires at least Java 6.
org.threeten.bp
with subpackages.java.time
.java.time
was first described.java.time
to Java 6 and 7 (ThreeTen for JSR-310).Upvotes: 5