要获得 2 个日期之间的差异,您可以使用 ThreeTen Backport,这是 Java 8 新日期/时间类的一个很好的反向移植。对于Android,还有ThreeTenABP(更多关于如何使用它here)。
首先我将字符串解析为LocalDateTime 对象,然后我得到了这些日期之间的差异。 API 创建了 2 个不同的“时间差/时间量”概念:Period,基于日期的时间量(以年、月和日表示)和Duration,时间-基于数量(以秒为单位)。
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
}
}
}
输出是:
1 天 1 秒
请注意,Period 类已经将字段(年、月和日)分开,而 Duration 类只保留秒数(因此需要进行一些计算才能获得正确的结果)——它实际上有方法像toHours(),但它只将秒转换为小时,并没有像我们想要的那样分隔所有字段。
您可以将append() 方法自定义为您想要的确切格式。我只是采用了简单的打印value + text的方式,大家可以根据需要进行更改。
Java 新的日期/时间 API
对于 Java >= 8,有 new java.time API。您可以使用这个新 API 和 ThreeTen Extra project,它具有 PeriodDuration 类(Period 和 Duration 的组合)。
代码与上面基本相同,唯一的区别是包名(在Java 8中是java.time,在ThreeTen Backport(或Android的ThreeTenABP)中是org.threeten.bp),但是类和方法名称相同。
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
当然你也可以使用org.threeten.bp的版本相同的代码创建Period和Duration。