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


当前回答

这是一个可行的选择。

public static String showDuration(LocalTime otherTime){          
    DateTimeFormatter df = DateTimeFormatter.ISO_LOCAL_TIME;
    LocalTime now = LocalTime.now();
    System.out.println("now: " + now);
    System.out.println("otherTime: " + otherTime);
    System.out.println("otherTime: " + otherTime.format(df));

    Duration span = Duration.between(otherTime, now);
    LocalTime fTime = LocalTime.ofNanoOfDay(span.toNanos());
    String output = fTime.format(df);

    System.out.println(output);
    return output;
}

使用

System.out.println(showDuration(LocalTime.of(9, 30, 0, 0)));

产生如下内容:

otherTime: 09:30
otherTime: 09:30:00
11:31:27.463
11:31:27.463

其他回答

String duration(Temporal from, Temporal to) {
    final StringBuilder builder = new StringBuilder();
    for (ChronoUnit unit : new ChronoUnit[]{YEARS, MONTHS, WEEKS, DAYS, HOURS, MINUTES, SECONDS}) {
        long amount = unit.between(from, to);
        if (amount == 0) {
            continue;
        }
        builder.append(' ')
                .append(amount)
                .append(' ')
                .append(unit.name().toLowerCase());
        from = from.plus(amount, unit);
    }
    return builder.toString().trim();
}

如果你不想拖进库,使用Formatter或相关的快捷方式就足够简单了。给定整数秒数s:

  String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60));

在scala中(我看到了一些其他的尝试,并没有留下深刻的印象):

def formatDuration(duration: Duration): String = {
  import duration._ // get access to all the members ;)
  f"$toDaysPart $toHoursPart%02d:$toMinutesPart%02d:$toSecondsPart%02d:$toMillisPart%03d"
}

看起来很可怕,是吗?好吧,这就是为什么我们使用ide来编写这些东西,以便方法调用($toHoursPart等)是不同的颜色。

f"…"是一个printf/String。格式样式字符串插补器(它允许$ code注入工作) 给定输出1 14:06:32.583,f插值的字符串将等效于string。格式(“1% 02 d: % 2 d: % 2 d。%03d", 14,6,32,583)

您可以使用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项目。

从Java 9开始,这变得更容易了。Duration仍然是不可格式化的,但是添加了获取小时、分钟和秒的方法,这使得任务更简单:

    LocalDateTime start = LocalDateTime.of(2019, Month.JANUARY, 17, 15, 24, 12);
    LocalDateTime end = LocalDateTime.of(2019, Month.JANUARY, 18, 15, 43, 33);
    Duration diff = Duration.between(start, end);
    String hms = String.format("%d:%02d:%02d", 
                                diff.toHours(), 
                                diff.toMinutesPart(), 
                                diff.toSecondsPart());
    System.out.println(hms);

这个代码片段的输出是:

24:19:21