Reputation: 493
I have three dates as String
objects in the format: dd:HH:mm:ss
00:1:9:14
00:3:10:4
00:3:39:49
How do I add these dates in Java to get the sum (00:7:59:07
)?
Sample code:
SimpleDateFormat sdf = new SimpleDateFormat("dd:HH:mm:ss");
Date d1 = sdf.parse("00:1:9:14");
Date d2 = sdf.parse("00:3:10:4");
Date d3 = sdf.parse("00:3:39:49");
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
Date d = new Date(d1.getTime() + d2.getTime() + d3.getTime());
System.out.println(d);
Output(wrong):
Wed Dec 31 01:09:14 IST 1969
Wed Dec 31 03:10:04 IST 1969
Wed Dec 31 03:39:49 IST 1969
Sun Dec 28 20:59:07 IST 1969
Upvotes: 2
Views: 3449
Reputation: 86324
Do your strings represent/denote amounts of time? So use the Duration
class. Let’s first write an auxiliary method that parses a string into a Duration
:
private static Duration parseDuration(String timeString) {
// First convert the string to ISO 8601 through a regex
String isoTimeString = timeString.replaceFirst("^(\\d+):(\\d+):(\\d+):(\\d+)$", "P$1DT$2H$3M$4S");
// Then parse into Duration
return Duration.parse(isoTimeString);
}
Duration.parse()
requires ISO 8601 format, it goes like PT1H9M14S
for a period of time of 1 hour 9 minutes 14 seconds. Or optionally P0DT1H9M14S
. The 0D
for 0 days goes before the T
. So I use a regular expression (AKA a regex) to modify your string format into ISO 8601 before parsing it. The $1
, $2
, etc., in the replacement string refer to what was matched inside the round brackets, the so-called groups in the regular expression.
Now we can add the times up:
String[] timeStrings = { "00:1:9:14", "00:3:10:4", "00:3:39:49" };
Duration totalTime = Duration.ZERO;
for (String timeString : timeStrings) {
Duration dur = parseDuration(timeString);
totalTime = totalTime.plus(dur);
}
System.out.println(totalTime);
Output:
PT7H59M7S
7 hours 59 minutes 7 seconds. If you want, you may format it back into your format of 00:7:59:07
. Search for how.
Your first mistake seems to have been before writing the code: thinking of the times as dates. They are not, and it would not make any sense to add dates. What is the sum of April 7 and December 25?
Mislead by this thinking, you tried to parse into Date
objects. A Date
is a point in time, not an amount of time, so this is wrong. Other than that the Date
class is poorly designed, and the SimpleDateFormat
class that you also tried to use is notoriously troublesome. Fortunately we’ve got no use for them here, and also for dates and times they are long outdated, superseded by java.time, the modern Java date and time API, of which Duration
is but one of many classes.
String.replaceFirst()
on the use of a regular expressionDuration
Duration
class.Upvotes: 1
Reputation: 561
private static String addTimes(String time1, String time2) throws ParseException {
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(dateFormat.parse(time1));
c2.setTime(dateFormat.parse(time2));
c1.add(Calendar.HOUR, c2.get(Calendar.HOUR));
c1.add(Calendar.MINUTE, c2.get(Calendar.MINUTE));
c1.add(Calendar.SECOND, c2.get(Calendar.SECOND));
return dateFormat.format(c1.getTime());
}
addTimes("1:9:14", "3:10:4");
Output: 04:19:18
Upvotes: 0
Reputation: 21
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
String s1 = "01:02:03";
String s2 = "10:12:13";
Date d1 = format.parse(s1);
Date d2 = format.parse(s2);
int sec = d1.getSeconds() + d2.getSeconds();
int min = d1.getMinutes() + d2.getMinutes();
int hr = d1.getHours() + d2.getHours();
Time sum = new Time(hr, min, sec);
System.out.println(sum); // Output: 11:14:16
Upvotes: 1
Reputation: 201467
The dd
format includes the day of the month. So your value of 00
will underflow if you use SimpleDateFormat
(or Java Date
because it also includes a day of the month). Instead, parse your time parts and do the math yourself.
For example, you could create a class TimePart
with days
, hours
, minutes
and seconds
like
static class TimePart {
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
static TimePart parse(String in) {
if (in != null) {
String[] arr = in.split(":");
TimePart tp = new TimePart();
tp.days = ((arr.length >= 1) ? Integer.parseInt(arr[0]) : 0);
tp.hours = ((arr.length >= 2) ? Integer.parseInt(arr[1]) : 0);
tp.minutes = ((arr.length >= 3) ? Integer.parseInt(arr[2]) : 0);
tp.seconds = ((arr.length >= 4) ? Integer.parseInt(arr[3]) : 0);
return tp;
}
return null;
}
public TimePart add(TimePart a) {
this.seconds += a.seconds;
int of = 0;
while (this.seconds >= 60) {
of++;
this.seconds -= 60;
}
this.minutes += a.minutes + of;
of = 0;
while (this.minutes >= 60) {
of++;
this.minutes -= 60;
}
this.hours += a.hours + of;
of = 0;
while (this.hours >= 24) {
of++;
this.hours -= 24;
}
this.days += a.days + of;
return this;
}
@Override
public String toString() {
return String.format("%02d:%02d:%02d:%02d", days, hours, minutes,
seconds);
}
}
Then your test-cases like
public static void main(String[] args) {
try {
TimePart d1 = TimePart.parse("00:1:9:14");
TimePart d2 = TimePart.parse("00:3:10:4");
TimePart d3 = TimePart.parse("00:3:39:49");
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
TimePart d4 = d1.add(d2).add(d3);
System.out.println(d4);
} catch (Exception e) {
e.printStackTrace();
}
}
And it seems to perform the addition correctly like
00:01:09:14
00:03:10:04
00:03:39:49
00:07:59:07
Upvotes: 2
Reputation: 1211
The above sum is arithmetic addition so you need a ref --here d0 (default epoch). Date class has a lot of problems beware...
SimpleDateFormat sdf = new SimpleDateFormat("dd:HH:mm:ss");
Date d0 = sdf.parse("00:00:00:00"); // ref
Date d1 = sdf.parse("00:01:09:14");
Date d2 = sdf.parse("00:03:10:04");
Date d3 = sdf.parse("00:03:39:49");
System.out.println(d0);
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
Date d = new Date(d1.getTime() + d2.getTime() + d3.getTime() - 2 * d0.getTime()); // impt
System.out.println(d);
Note:- Date addition is not an easy task, think twice.
Upvotes: 1