我想用H:MM:SS这样的模式以秒为单位格式化持续时间。java中当前的实用程序设计用于格式化时间,而不是持续时间。


当前回答

在java8中还有另一种方法。但如果持续时间不超过24小时,则有效

public String formatDuration(Duration duration) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm.SSS");
    return LocalTime.ofNanoOfDay(duration.toNanos()).format(formatter);
}

其他回答

我的库Time4J提供了一个基于模式的解决方案(类似于Apache DurationFormatUtils,但更灵活):

Duration<ClockUnit> duration =
    Duration.of(-573421, ClockUnit.SECONDS) // input in seconds only
    .with(Duration.STD_CLOCK_PERIOD); // performs normalization to h:mm:ss-structure
String fs = Duration.formatter(ClockUnit.class, "+##h:mm:ss").format(duration);
System.out.println(fs); // output => -159:17:01

这段代码演示了处理小时溢出和符号处理的功能,请参见基于模式的持续时间格式化程序的API。

这个答案只使用Duration方法,适用于Java 8:

public static String format(Duration d) {
    long days = d.toDays();
    d = d.minusDays(days);
    long hours = d.toHours();
    d = d.minusHours(hours);
    long minutes = d.toMinutes();
    d = d.minusMinutes(minutes);
    long seconds = d.getSeconds() ;
    return 
            (days ==  0?"":days+" days,")+ 
            (hours == 0?"":hours+" hours,")+ 
            (minutes ==  0?"":minutes+" minutes,")+ 
            (seconds == 0?"":seconds+" seconds,");
}

您可以使用java.time.Duration,它以ISO-8601标准为模型,是作为JSR-310实现的一部分由Java-8引入的。在Java-9中引入了一些更方便的方法。

演示:

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Month;

public class Main {
    public static void main(String[] args) {
        LocalDateTime startDateTime = LocalDateTime.of(2020, Month.DECEMBER, 10, 15, 20, 25);
        LocalDateTime endDateTime = LocalDateTime.of(2020, Month.DECEMBER, 10, 18, 24, 30);

        Duration duration = Duration.between(startDateTime, endDateTime);
        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedElapsedTime = String.format("%02d:%02d:%02d", duration.toHours() % 24,
                duration.toMinutes() % 60, duration.toSeconds() % 60);
        System.out.println(formattedElapsedTime);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedElapsedTime = String.format("%02d:%02d:%02d", duration.toHoursPart(), duration.toMinutesPart(),
                duration.toSecondsPart());
        System.out.println(formattedElapsedTime);
        // ##############################################################################
    }
}

输出:

PT3H4M5S
03:04:05
03:04:05

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

无论出于何种原因,如果您必须坚持使用Java 6或Java 7,您可以使用ThreeTen-Backport,它可以向后移植大部分Java。Java 6和7的时间功能。 如果你正在为一个Android项目工作,你的Android API级别仍然不兼容Java-8,检查Java 8+ API通过desugaring和如何使用ThreeTenABP在Android项目。

下面是另一个如何格式化持续时间的示例。 注意,这个示例将正持续时间和负持续时间都显示为正持续时间。

import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.HOURS;
import static java.time.temporal.ChronoUnit.MINUTES;
import static java.time.temporal.ChronoUnit.SECONDS;

import java.time.Duration;

public class DurationSample {
    public static void main(String[] args) {
        //Let's say duration of 2days 3hours 12minutes and 46seconds
        Duration d = Duration.ZERO.plus(2, DAYS).plus(3, HOURS).plus(12, MINUTES).plus(46, SECONDS);

        //in case of negative duration
        if(d.isNegative()) d = d.negated();

        //format DAYS HOURS MINUTES SECONDS 
        System.out.printf("Total duration is %sdays %shrs %smin %ssec.\n", d.toDays(), d.toHours() % 24, d.toMinutes() % 60, d.getSeconds() % 60);

        //or format HOURS MINUTES SECONDS 
        System.out.printf("Or total duration is %shrs %smin %sec.\n", d.toHours(), d.toMinutes() % 60, d.getSeconds() % 60);

        //or format MINUTES SECONDS 
        System.out.printf("Or total duration is %smin %ssec.\n", d.toMinutes(), d.getSeconds() % 60);

        //or format SECONDS only 
        System.out.printf("Or total duration is %ssec.\n", d.getSeconds());
    }
}

查看所有这些计算,大多数单位(小时、分钟等)都有一个. tofoopart()方便方法,这可能是有帮助的。

E.g.

Duration.ofMinutes(110L).toMinutesPart() == 50

读:到父单位(小时)的下一个值的分钟数。