import java.time.*;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main
(String[] args
) { Duration duration = Duration.between(
ZonedDateTime.now().minusHours(4).minusMinutes(1).minusSeconds(40),
ZonedDateTime.now()
);
System.
out.
println(formatDuration
(duration
));
// Example for '... later'
duration = Duration.between(
ZonedDateTime.now().plusHours(4).plusMinutes(1).plusSeconds(40),
ZonedDateTime.now()
);
System.
out.
println(formatDuration
(duration
)); }
static String formatDuration
(Duration duration
) { //################# Java 9 onwards ###################
fmtMin
(Math.
abs(duration.
toMinutesPart())),
fmtSec
(Math.
abs(duration.
toSecondsPart())) ).stream().collect(Collectors.joining(", "));
//#####################################################
return formatted += duration.toHoursPart() >= 0 ? " ago." : " later.";
}
static String fmtHr
(long hr
) { return String.
format("%d %s", hr, hr
<= 1 ? "hour" : "hours"); }
static String fmtMin
(long min
) { return String.
format("%d %s", min, min
<= 1 ? "minute" : "minutes"); }
static String fmtSec
(long sec
) { return String.
format("%d %s", sec, sec
<= 1 ? "second" : "seconds"); }
}
aW1wb3J0IGphdmEudGltZS4qOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CgpwdWJsaWMgY2xhc3MgTWFpbiB7CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgRHVyYXRpb24gZHVyYXRpb24gPSBEdXJhdGlvbi5iZXR3ZWVuKAogICAgICAgICAgICAgICAgWm9uZWREYXRlVGltZS5ub3coKS5taW51c0hvdXJzKDQpLm1pbnVzTWludXRlcygxKS5taW51c1NlY29uZHMoNDApLAogICAgICAgICAgICAgICAgWm9uZWREYXRlVGltZS5ub3coKQogICAgICAgICk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZvcm1hdER1cmF0aW9uKGR1cmF0aW9uKSk7CgogICAgICAgIC8vIEV4YW1wbGUgZm9yICcuLi4gbGF0ZXInCiAgICAgICAgZHVyYXRpb24gPSBEdXJhdGlvbi5iZXR3ZWVuKAogICAgICAgICAgICAgICAgWm9uZWREYXRlVGltZS5ub3coKS5wbHVzSG91cnMoNCkucGx1c01pbnV0ZXMoMSkucGx1c1NlY29uZHMoNDApLAogICAgICAgICAgICAgICAgWm9uZWREYXRlVGltZS5ub3coKQogICAgICAgICk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZvcm1hdER1cmF0aW9uKGR1cmF0aW9uKSk7CiAgICB9CgogICAgc3RhdGljIFN0cmluZyBmb3JtYXREdXJhdGlvbihEdXJhdGlvbiBkdXJhdGlvbikgewogICAgICAgIC8vIyMjIyMjIyMjIyMjIyMjIyMgSmF2YSA5IG9ud2FyZHMgIyMjIyMjIyMjIyMjIyMjIyMjIwogICAgICAgIFN0cmluZyBmb3JtYXR0ZWQgPSBMaXN0Lm9mKGZtdEhyKE1hdGguYWJzKGR1cmF0aW9uLnRvSG91cnNQYXJ0KCkpKSwKICAgICAgICAgICAgICAgIGZtdE1pbihNYXRoLmFicyhkdXJhdGlvbi50b01pbnV0ZXNQYXJ0KCkpKSwKICAgICAgICAgICAgICAgIGZtdFNlYyhNYXRoLmFicyhkdXJhdGlvbi50b1NlY29uZHNQYXJ0KCkpKQogICAgICAgICkuc3RyZWFtKCkuY29sbGVjdChDb2xsZWN0b3JzLmpvaW5pbmcoIiwgIikpOwogICAgICAgIC8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCiAgICAgICAgcmV0dXJuIGZvcm1hdHRlZCArPSBkdXJhdGlvbi50b0hvdXJzUGFydCgpID49IDAgPyAiIGFnby4iIDogIiBsYXRlci4iOwogICAgfQoKICAgIHN0YXRpYyBTdHJpbmcgZm10SHIobG9uZyBocikgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIlZCAlcyIsIGhyLCBociA8PSAxID8gImhvdXIiIDogImhvdXJzIik7CiAgICB9CgogICAgc3RhdGljIFN0cmluZyBmbXRNaW4obG9uZyBtaW4pIHsKICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiJWQgJXMiLCBtaW4sIG1pbiA8PSAxID8gIm1pbnV0ZSIgOiAibWludXRlcyIpOwogICAgfQoKICAgIHN0YXRpYyBTdHJpbmcgZm10U2VjKGxvbmcgc2VjKSB7CiAgICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIiVkICVzIiwgc2VjLCBzZWMgPD0gMSA/ICJzZWNvbmQiIDogInNlY29uZHMiKTsKICAgIH0KfQ==