代码之家  ›  专栏  ›  技术社区  ›  phatmanace

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

  •  64
  • phatmanace  · 技术社区  · 14 年前

    有人知道一个Java库,它可以用C语言一样的毫秒打印一个数字吗?

    例如,123456 ms作为长将打印为4d1h3m5。

    10 回复  |  直到 5 年前
        1
  •  82
  •   Erick Robertson    10 年前

    Joda Time 使用 PeriodFormatterBuilder .

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

    例如

    //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);
    
        2
  •  35
  •   StepTNT    7 年前

    我用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 .

        3
  •  9
  •   skaffman    14 年前

    JodaTime 有一个 Period 可以表示此类数量的类,并且可以通过 IsoPeriodFormat ISO8601 格式,例如 PT4D1H3M5S ,例如

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

    如果不是你想要的格式,那么 PeriodFormatterBuilder 允许您组装任意布局,包括C样式 4d1h3m5s .

        4
  •  9
  •   noleto Zhilong Jia    11 年前

    ApacheCommonsLang也提供了一个有用的类来完成这项工作。 DurationFormatUtils

    例如 DurationFormatUtils.formatDurationHMS( 15362 * 1000 ) ) =>4:16:02.000(h:m:s.millis) DurationFormatUtils.formatDurationISO( 15362 * 1000 ) ) =>p0y0M0dt4h16m2.000s,参考ISO8601

        5
  •  9
  •   Basil Bourque    8 年前

    用Java 8也可以使用 toString() 方法 java.time.Duration 要在不使用外部库的情况下格式化它,请使用 ISO 8601 seconds based representation 如pt8h6m12.345s。

        6
  •  6
  •   Robert H Odomontois    11 年前

    以下是使用纯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()); 
    
        7
  •  4
  •   Nick    7 年前

    我知道这可能不完全适合您的用例,但是 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”
    
        8
  •  3
  •   erickdeoliveiraleal    5 年前

    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
  •  2
  •   Meno Hochschild    9 年前

    一个替代乔达时代的建设者方法是 基于模式的解决方案 . 这是我的图书馆提供的 时间4J . 使用类的示例 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
    
        10
  •  2
  •   Torsten    6 年前

    爪哇8 版本基于 user678573's answer :

        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中没有周期格式化程序,而且没有像GethRes、GETMIX、……这样的方法…

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