Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java subtract two dates in this format [duplicate]

Tags:

java

Possible Duplicate:
Calculating difference in dates in Java
How do you subtract Dates in Java?

I am parsing two dates from a string that look like:

Oct 15, 2012 1:07:13 PM
Oct 23, 2012 03:43:34 PM

What I need to do is find the difference between these two dates, ex:

Oct 23, 2012 03:43:34 PM - Oct 15, 2012 1:07:13 PM

= 8 days 2 hours 36 minutes 21 seconds

^ This is what I need to get with the two date/times I have

I believe I need to parse the format and convert it to another format, then subtract the difference between and do the math to get the days/hours/minutes/seconds between

like image 988
Jsn0605 Avatar asked Oct 23 '12 18:10

Jsn0605


People also ask

How do you subtract two dates in Java?

Find the time difference between two dates in milliseconds by using the method getTime() in Java as d2. getTime() – d1. getTime(). Use date-time mathematical formula to find the difference between two dates.

Can we compare dates of different formats in Java?

In Java, two dates can be compared using the compareTo() method of Comparable interface. This method returns '0' if both the dates are equal, it returns a value "greater than 0" if date1 is after date2 and it returns a value "less than 0" if date1 is before date2.

How do you subtract two date columns?

Calculate the difference in days Select cell D2, which is the first blank cell in the Duration column. Type =C2-B2, and then press RETURN . Excel displays the result as the number of days between the two dates (104). Select cell D2.


1 Answers

In contrary to what other answerers try to imply, calculating the difference between two dates isn't that trivial in standard Java SE.

Your first step is indeed to convert those strings to useable Date instances. You can do this using SimpleDateFormat. Here's a kickoff example:

String string1 = "Oct 15, 2012 1:07:13 PM";
String string2 = "Oct 23, 2012 03:43:34 PM";

SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy h:mm:ss a", Locale.ENGLISH);

Date date1 = sdf.parse(string1);
Date date2 = sdf.parse(string2);

(please note the importance of the optional Locale argument here, this is often overlooked in answers about converting strings to dates)

Your next step is calculating the difference between those 2 dates. This is a terrible job when you are restricted to the standard Java SE API. Best what you can get is the java.util.Calendar.


Note that you could of course substract the milliseconds and calculate the difference using the usual arithmetic operators.

long differenceInMillis = date2.getTime() - date1.getTime();
// ...

But this naive approach doesn't take leap years into account, let alone daylight saving time and local-specific changes in datetime.


As to the java.util.Calendar approach, you basically need to use Calendar#add() in a counter loop to get the elapsed value for years, months and days. This takes leap years, daylight saving time and local-specific disturbances in time properly into account.

First create this helper method to eliminate some boilerplate code:

public static int elapsed(Calendar before, Calendar after, int field) {
    Calendar clone = (Calendar) before.clone(); // Otherwise changes are been reflected.
    int elapsed = -1;
    while (!clone.after(after)) {
        clone.add(field, 1);
        elapsed++;
    }
    return elapsed;
}

Now you can calculate the elapsed time as follows:

Calendar start = Calendar.getInstance();
start.setTime(date1);
Calendar end = Calendar.getInstance();
end.setTime(date2);

Integer[] elapsed = new Integer[6];
Calendar clone = (Calendar) start.clone(); // Otherwise changes are been reflected.
elapsed[0] = elapsed(clone, end, Calendar.YEAR);
clone.add(Calendar.YEAR, elapsed[0]);
elapsed[1] = elapsed(clone, end, Calendar.MONTH);
clone.add(Calendar.MONTH, elapsed[1]);
elapsed[2] = elapsed(clone, end, Calendar.DATE);
clone.add(Calendar.DATE, elapsed[2]);
elapsed[3] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 3600000;
clone.add(Calendar.HOUR, elapsed[3]);
elapsed[4] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 60000;
clone.add(Calendar.MINUTE, elapsed[4]);
elapsed[5] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 1000;

System.out.format("%d years, %d months, %d days, %d hours, %d minutes, %d seconds", elapsed);

Pretty ugly, yeah.

If you going to work with date and time in Java pretty often, then you may find Joda time the walhalla. Here's a concrete kickoff example of how you could do it all with pure Joda Time:

String string1 = "Oct 15, 2012 1:07:13 PM";
String string2 = "Oct 23, 2012 03:43:34 PM";

DateTimeFormatter dtf = DateTimeFormat.forPattern("MMM d, yyyy h:mm:ss a").withLocale(Locale.ENGLISH);

DateTime dateTime1 = dtf.parseDateTime(string1);
DateTime dateTime2 = dtf.parseDateTime(string2);
Period period = new Period(dateTime1, dateTime2);

PeriodFormatter formatter = new PeriodFormatterBuilder()
    .appendYears().appendSuffix(" years ")
    .appendMonths().appendSuffix(" months ")
    .appendWeeks().appendSuffix(" weeks ")
    .appendDays().appendSuffix(" days ")
    .appendHours().appendSuffix(" hours ")
    .appendMinutes().appendSuffix(" minutes ")
    .appendSeconds().appendSuffix(" seconds ")
    .printZeroNever()
    .toFormatter();

String elapsed = formatter.print(period);
System.out.println(elapsed);

Much better, right? The plural "s" needs some work though, but that's beyond the question.

like image 102
BalusC Avatar answered Oct 23 '22 16:10

BalusC