如何在Java中“漂亮地打印”持续时间?

时间:2010-08-12 19:42:20

标签: java datetime date time

有没有人知道一个Java库可以在几毫秒内以与C#相同的方式打印数字?

例如,123456 ms作为长整数将被打印为4d1h3m5s。

12 个答案:

答案 0 :(得分:83)

使用Joda Time

PeriodFormatterBuilder可以很好地完成此操作。

快速获胜:PeriodFormat.getDefault().print(duration.toPeriod());

e.g。

//import org.joda.time.format.PeriodFormatter;
//import org.joda.time.format.PeriodFormatterBuilder;
//import org.joda.time.Duration;

Duration duration = new Duration(123456); // in milliseconds
PeriodFormatter formatter = new PeriodFormatterBuilder()
     .appendDays()
     .appendSuffix("d")
     .appendHours()
     .appendSuffix("h")
     .appendMinutes()
     .appendSuffix("m")
     .appendSeconds()
     .appendSuffix("s")
     .toFormatter();
String formatted = formatter.print(duration.toPeriod());
System.out.println(formatted);

答案 1 :(得分:44)

我使用Java 8的Duration.toString()和一些正则表达式构建了一个简单的解决方案:

public static String humanReadableFormat(Duration duration) {
    return duration.toString()
            .substring(2)
            .replaceAll("(\\d[HMS])(?!$)", "$1 ")
            .toLowerCase();
}

结果如下:

- 5h
- 7h 15m
- 6h 50m 15s
- 2h 5s
- 0.1s

如果您不想要空格,只需删除replaceAll

答案 2 :(得分:9)

JodaTime有一个Period类,可以代表这样的数量,并且可以IsoPeriodFormat格式呈现(通过ISO8601),例如PT4D1H3M5S,例如

Period period = new Period(millis);
String formatted = ISOPeriodFormat.standard().print(period);

如果该格式不是您想要的格式,那么PeriodFormatterBuilder可让您组合任意布局,包括您的C#风格4d1h3m5s

答案 3 :(得分:9)

Apache commons-lang提供了一个有用的类来完成这项工作DurationFormatUtils

e.g。 DurationFormatUtils.formatDurationHMS( 15362 * 1000 ) ) => 4:16:02.000(H:m:s.millis) DurationFormatUtils.formatDurationISO( 15362 * 1000 ) ) => P0Y0M0DT4H16M2.000S,参见ISO8601

答案 4 :(得分:9)

使用Java 8,您还可以使用toString()java.time.Duration方法在不使用ISO 8601 seconds based representation的外部库(如PT8H6M12.345S)的情况下对其进行格式化。

答案 5 :(得分:6)

以下是使用纯JDK代码的方法:

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;

long diffTime = 215081000L;
Duration duration = DatatypeFactory.newInstance().newDuration(diffTime);

System.out.printf("%02d:%02d:%02d", duration.getDays() * 24 + duration.getHours(), duration.getMinutes(), duration.getSeconds()); 

答案 6 :(得分:4)

我意识到这可能不完全适合您的用例,但PrettyTime在这里可能很有用。

PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
//prints: “right now”

System.out.println(p.format(new Date(1000*60*10)));
//prints: “10 minutes from now”

答案 7 :(得分:3)

Joda-Time的构建器方法的替代方案是基于模式的解决方案。这是我的图书馆 Time4J 提供的。使用类Duration.Formatter的示例(添加了一些空格以提高可读性 - 删除空格将产生希望的C#风格):

IsoUnit unit = ClockUnit.MILLIS;
Duration<IsoUnit> dur = Duration.of(123456, unit).with(Duration.STD_PERIOD);
String s = Duration.Formatter.ofPattern("D'd' h'h' m'm' s.fff's'").format(dur);
System.out.println(s); // output: 0d 0h 2m 3.456s

另一种方法是使用类net.time4j.PrettyTime(这也适用于本地化输出和打印相对时间):

s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.NARROW);
System.out.println(s); // output: 2m 3s 456ms

答案 8 :(得分:3)

Java 9 +

Duration d1 = Duration.ofDays(0);
        d1 = d1.plusHours(47);
        d1 = d1.plusMinutes(124);
        d1 = d1.plusSeconds(124);
System.out.println(String.format("%s d %sh %sm %ss", 
                d1.toDaysPart(), 
                d1.toHoursPart(), 
                d1.toMinutesPart(), 
                d1.toSecondsPart()));

2 d 1h 6m 4s

答案 9 :(得分:3)

org.threeten.extra.AmountFormats.wordBased

ThreeTen-Extra项目由JSR 310, java.time Joda-Time 的作者Stephen Colebourne维护。 {3}}类,可与标准Java 8日期时间类一起使用。不过,它相当冗长,没有其他选项可实现更紧凑的输出。

Duration d = Duration.ofMinutes(1).plusSeconds(9).plusMillis(86);
System.out.println(AmountFormats.wordBased(d, Locale.getDefault());

1 minute, 9 seconds and 86 milliseconds

答案 10 :(得分:2)

基于user678573's answer Java 8 版本:

    private static String humanReadableFormat(Duration duration) {
    return String.format("%s days and %sh %sm %ss", duration.toDays(),
            duration.toHours() - TimeUnit.DAYS.toHours(duration.toDays()),
            duration.toMinutes() - TimeUnit.HOURS.toMinutes(duration.toHours()),
            duration.getSeconds() - TimeUnit.MINUTES.toSeconds(duration.toMinutes()));
}

...因为Java 8中没有PeriodFormatter,也没有诸如getHours,getMinutes等方法...

我很高兴看到Java 8的更好版本。

答案 11 :(得分:1)

另一个 Java 9+ 解决方案:

private String formatDuration(Duration duration) {
    List<String> parts = new ArrayList<>();
    long days = duration.toDaysPart();
    if (days > 0) {
        parts.add(plural(days, "day"));
    }
    int hours = duration.toHoursPart();
    if (hours > 0 || !parts.isEmpty()) {
        parts.add(plural(hours, "hour"));
    }
    int minutes = duration.toMinutesPart();
    if (minutes > 0 || !parts.isEmpty()) {
        parts.add(plural(minutes, "minute"));
    }
    int seconds = duration.toSecondsPart();
    parts.add(plural(seconds, "second"));
    return String.join(", ", parts);
}

private String plural(long num, String unit) {
    return num + " " + unit + (num == 1 ? "" : "s");
}

例如,

6 days, 21 hours, 2 minutes, 14 seconds