Basil Bourque 已经给出了一个很好的答案。在你的 cmets 之后,我想我可以更具体一点:
public static String diff(String thenStr) {
Instant now = Instant.now();
Instant then = Instant.parse(thenStr);
ChronoUnit[] units = ChronoUnit.values();
// try longest units first, they are in the far end of the array
for (int i = units.length - 1; i >= 0; i--) {
if (then.isSupported(units[i])) {
long diffInCurrentUnit = units[i].between(then, now);
if (diffInCurrentUnit != 0) {
return "" + diffInCurrentUnit + ' ' + units[i].toString().toLowerCase();
}
}
}
return "0";
}
让我们试试吧:
System.out.println(diff("2019-02-23T16:50:21Z"));
System.out.println(diff("2019-02-23T20:15:21Z"));
刚刚运行时的输出:
3 hours
36 seconds
我使用的进口产品:
import org.threeten.bp.Instant;
import org.threeten.bp.temporal.ChronoUnit;
import org.threeten.bp.temporal.UnsupportedTemporalTypeException;
Instant 不支持比天更粗的单位(24 小时)。如果您需要能够返回数周、数月或数年,只需使用 OffsetDateTime 而不是 Instant。
问题:我可以在我的 Android API 级别上使用 java.time 吗?
是的,java.time 在较旧和较新的 Android 设备上运行良好。它只需要至少 Java 6。
- 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 开始)中,现代 API 是内置的。在这种情况下,从带有子包的
java.time 导入。
- 在 Java 6 和 7 中获得 ThreeTen Backport,这是现代类的后向端口(JSR 310 的 ThreeTen;请参阅底部的链接)。
- 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从
org.threeten.bp 导入日期和时间类以及子包。
流?
编辑:@Basil Bourque 在评论中问道:
我想知道这是否可以被压缩成一条溪流,也许是一条单线?
可以,但我认为在这种情况下不会有优势:
return IntStream.range(0, units.length)
.map(i -> units.length - i - 1)
.mapToObj(i -> units[i])
.filter(then::isSupported)
.filter(unit -> unit.between(then, now) != 0)
.map(unit -> "" + unit.between(then, now) + ' ' + unit.toString().toLowerCase())
.findFirst()
.orElse("0");
我发现返回数组元素的代码.map(i -> units.length - i - 1) 有点难以阅读。我们需要计算两次差异,第一次用于过滤,然后用于组装字符串结果。但它有效,如果你愿意,你可以使用它。
使用内部流管道可以避免双重计算,但同样难以阅读:
.flatMap(unit -> LongStream.of(unit.between(then, now))
.filter(diff -> diff != 0)
.mapToObj(diff -> "" + diff + ' ' + unit.toString().toLowerCase()))
链接