To get the difference between 2 dates, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).
First I parsed the strings to a LocalDateTime
object, then I've got the difference between those dates. The API has created 2 different concepts of "time-difference/amount of time": a Period
, a date-based amount of time (in terms of years, months and days), and a Duration
, a time-based amount (in terms of seconds).
import org.threeten.bp.Duration;
import org.threeten.bp.LocalDate;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.LocalTime;
import org.threeten.bp.Period;
import org.threeten.bp.format.DateTimeFormatter;
String time1 = "2017-06-18 07:00:00"; // set time
String curtime = "2017-06-19 07:00:01"; // get the current time
// parse the strings to a date object
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime t1 = LocalDateTime.parse(time1, fmt);
LocalDateTime cur = LocalDateTime.parse(curtime, fmt);
// get the period between the dates
LocalDate startDate = t1.toLocalDate();
LocalDate endDate = cur.toLocalDate();
Period period = Period.ZERO;
if (startDate != null && endDate != null) {
period = Period.between(startDate, endDate);
}
// get the duration between the dates
LocalTime startTime = t1.toLocalTime();
LocalTime endTime = cur.toLocalTime();
startTime = startTime != null ? startTime : LocalTime.MIDNIGHT;
endTime = endTime != null ? endTime : LocalTime.MIDNIGHT;
Duration duration = Duration.between(startTime, endTime);
StringBuilder sb = new StringBuilder();
append(sb, period.getYears(), "year");
append(sb, period.getMonths(), "month");
append(sb, period.getDays(), "day");
long seconds = duration.getSeconds();
long hours = seconds / 3600;
append(sb, hours, "hour");
seconds -= (hours * 3600);
long minutes = seconds / 60;
append(sb, minutes, "minute");
seconds -= (minutes * 60);
append(sb, seconds, "second");
System.out.println(sb.toString()); // 1 day 1 second
// auxiliary method
public void append(StringBuilder sb, long value, String text) {
if (value > 0) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(value).append(" ");
sb.append(text);
if (value > 1) {
sb.append("s"); // append "s" for plural
}
}
}
The output is:
1 day 1 second
Note that the Period
class already keeps the fields (years, months and days) separated, while the Duration
class keeps only the seconds (so some calculations are needed to get the correct results) - it actually has methods like toHours()
, but it only converts the seconds to hours, and it doesn't separate all the fields like we want.
You can customize the append()
method to the exact format you want. I just took the simple approach of printing value + text
, but you can change it according to your needs.
Java new Date/Time API
For Java >= 8, there's the new java.time API. You can use this new API and the ThreeTen Extra project, which has the PeriodDuration
class (a combination of both Period
and Duration
).
The code is basically the same as above, the only difference is the packages names (in Java 8 is java.time
and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp
), but the classes and methods names are the same.
import org.threeten.extra.PeriodDuration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
String time1 = "2017-06-18 07:00:00"; // set time
String curtime = "2017-06-19 07:00:01"; // get the current time
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime t1 = LocalDateTime.parse(time1, fmt);
LocalDateTime cur = LocalDateTime.parse(curtime, fmt);
PeriodDuration pd = PeriodDuration.between(t1, cur);
StringBuilder sb = new StringBuilder();
append(sb, pd.getPeriod().getYears(), "year");
append(sb, pd.getPeriod().getMonths(), "month");
append(sb, pd.getPeriod().getDays(), "day");
long seconds = pd.getDuration().getSeconds();
long hours = seconds / 3600;
append(sb, hours, "hour");
seconds -= (hours * 3600);
long minutes = seconds / 60;
append(sb, minutes, "minute");
seconds -= (minutes * 60);
append(sb, seconds, "second");
System.out.println(sb.toString()); // 1 day 1 second
Of course you can also create a Period
and a Duration
using the same code of org.threeten.bp
's version.