Kalyan Ghosh
Kalyan Ghosh

Reputation: 493

Java add dates of format dd:HH:mm:ss

I have three dates as String objects in the format: dd:HH:mm:ss

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

Answers (5)

Anonymous
Anonymous

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.

What went wrong in your code?

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.

Links

Upvotes: 1

Milan Paudyal
Milan Paudyal

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

Chetan Sachdeva
Chetan Sachdeva

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

Elliott Frisch
Elliott Frisch

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

Mitesh Pathak
Mitesh Pathak

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

Related Questions