如何获取两个 ZonedDateTimes 之间的时间差并漂亮地打印它,如“4 小时 1 分 40 秒前”?

问题描述 投票:0回答:2

这就是我调用

getTimeBetween
函数的方式:

getTimeBetween(ZonedDateTime.now().minusHours(4).minusMinutes(1).minusSeconds(40), ZonedDateTime.now());

我期望这个输出:

4 hours, 1 minute, 40 seconds ago

这是我的

getTimeBetween
功能:

private String getTimeBetween(ZonedDateTime zonedDateTime1, ZonedDateTime zonedDateTime2) {
    Duration timeDifference = Duration.between(zonedDateTime1, zonedDateTime2);
    if (timeDifference.getSeconds() == 0) return "now";
    String timeDifferenceAsPrettyString = "";
    Boolean putComma = false;
    if (timeDifference.toDays() > 0) {
        if (timeDifference.toDays() == 1) timeDifferenceAsPrettyString += timeDifference.toDays() + " day";
        else timeDifferenceAsPrettyString += timeDifference.toDays() + " days";
        putComma = true;
    }
    if (timeDifference.toHours() > 0) {
        if (putComma) timeDifferenceAsPrettyString += ", ";
        if (timeDifference.toHours() == 1) timeDifferenceAsPrettyString += timeDifference.toHours() + " hour";
        else timeDifferenceAsPrettyString += timeDifference.toHours() % 24 + " hours";
        putComma = true;
    }
    if (timeDifference.toMinutes() > 0) {
        if (putComma) timeDifferenceAsPrettyString += ", ";
        if (timeDifference.toMinutes() == 1) timeDifferenceAsPrettyString += timeDifference.toMinutes() + " minute";
        else timeDifferenceAsPrettyString += timeDifference.toMinutes() % 60 + " minutes";
        putComma = true;
    }
    if (timeDifference.getSeconds() > 0) {
        if (putComma) timeDifferenceAsPrettyString += ", ";
        if (timeDifference.getSeconds() == 1) timeDifferenceAsPrettyString += timeDifference.getSeconds() + " second";
        else timeDifferenceAsPrettyString += timeDifference.getSeconds() % 60 + " seconds";
    }
    timeDifferenceAsPrettyString += " ago";
    return timeDifferenceAsPrettyString;
}

这个功能按预期工作,但是真的有必要这样做吗?也许有更好的方法来实现这一目标?

我正在使用 Java 8。

java refactoring zoneddatetime
2个回答
1
投票

这个怎么样?

static String getTimeBetween(ZonedDateTime from, ZonedDateTime to) {
    StringBuilder builder = new StringBuilder();
    long epochA = from.toEpochSecond(), epochB = to.toEpochSecond();
    long secs = Math.abs(epochB - epochA);
    if (secs == 0) return "now";
    Map<String, Integer> units = new LinkedHashMap<>();
    units.put("day", 86400);
    units.put("hour", 3600);
    units.put("minute", 60);
    units.put("second", 1);
    boolean separator = false;
    for (Map.Entry<String, Integer> unit : units.entrySet()) {
        if (secs >= unit.getValue()) {
            long count = secs / unit.getValue();
            if (separator) builder.append(", ");
            builder.append(count).append(' ').append(unit.getKey());
            if (count != 1) builder.append('s');
            secs %= unit.getValue();
            separator = true;
        }
    }
    return builder.append(epochA > epochB ? " ago" : " in the future").toString();
}

您可能可以存储

LinkedHashMap
而不是每次方法调用都实例化它,但这应该可行。


0
投票

您可以使用

java.time.Duration
,它以 ISO-8601 标准为模型,并作为 JSR-310 实施的一部分引入。

演示:

import java.time.*;

public class Main {
    public static void main(String[] args) {
        Duration duration = Duration.between(
                ZonedDateTime.now().minusHours(4).minusMinutes(1).minusSeconds(40),
                ZonedDateTime.now()
        );

        // Print it in the default format
        System.out.println(duration);

        // Print it in a custom format
        //################# Java 8 ####################
        System.out.printf("%s %s %s%n", fmtHrs(duration.toHours()), fmtMin(duration.toMinutes() % 60), fmtSec(duration.toSeconds() % 60));
        //#####################################################

        //################# Java 9 onwards ####################
        System.out.printf("%s %s %s%n", fmtHrs(duration.toHours()), fmtMin(duration.toMinutesPart()), fmtSec(duration.toSecondsPart()));
        //#####################################################
    }

    static String fmtHrs(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");
    }
}

输出:

PT4H1M40.0050174S
4 hours 1 minute 40 seconds
4 hours 1 minute 40 seconds

在线演示

Trail:日期时间了解现代日期时间 API。

© www.soinside.com 2019 - 2024. All rights reserved.