我想用H:MM:SS这样的模式以秒为单位格式化持续时间。java中当前的实用程序设计用于格式化时间,而不是持续时间。
当前回答
这个答案只使用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 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
您可以使用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项目。
在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 8的Java .time来实现这一点,这是一个很好的解决方案:
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.UnsupportedTemporalTypeException;
public class TemporalDuration implements TemporalAccessor {
private static final Temporal BASE_TEMPORAL = LocalDateTime.of(0, 1, 1, 0, 0);
private final Duration duration;
private final Temporal temporal;
public TemporalDuration(Duration duration) {
this.duration = duration;
this.temporal = duration.addTo(BASE_TEMPORAL);
}
@Override
public boolean isSupported(TemporalField field) {
if(!temporal.isSupported(field)) return false;
long value = temporal.getLong(field)-BASE_TEMPORAL.getLong(field);
return value!=0L;
}
@Override
public long getLong(TemporalField field) {
if(!isSupported(field)) throw new UnsupportedTemporalTypeException(new StringBuilder().append(field.toString()).toString());
return temporal.getLong(field)-BASE_TEMPORAL.getLong(field);
}
public Duration getDuration() {
return duration;
}
@Override
public String toString() {
return dtf.format(this);
}
private static final DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.optionalStart()//second
.optionalStart()//minute
.optionalStart()//hour
.optionalStart()//day
.optionalStart()//month
.optionalStart()//year
.appendValue(ChronoField.YEAR).appendLiteral(" Years ").optionalEnd()
.appendValue(ChronoField.MONTH_OF_YEAR).appendLiteral(" Months ").optionalEnd()
.appendValue(ChronoField.DAY_OF_MONTH).appendLiteral(" Days ").optionalEnd()
.appendValue(ChronoField.HOUR_OF_DAY).appendLiteral(" Hours ").optionalEnd()
.appendValue(ChronoField.MINUTE_OF_HOUR).appendLiteral(" Minutes ").optionalEnd()
.appendValue(ChronoField.SECOND_OF_MINUTE).appendLiteral(" Seconds").optionalEnd()
.toFormatter();
}
在java8中还有另一种方法。但如果持续时间不超过24小时,则有效
public String formatDuration(Duration duration) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm.SSS");
return LocalTime.ofNanoOfDay(duration.toNanos()).format(formatter);
}
推荐文章
- Eclipse调试器总是阻塞在ThreadPoolExecutor上,没有任何明显的异常,为什么?
- Java生成两个给定值之间的随机数
- 如何有效地从数组列表或字符串数组中删除所有空元素?
- 比较JUnit断言中的数组,简洁的内置方式?
- codestyle;把javadoc放在注释之前还是之后?
- 如何在Spring中定义List bean ?
- 将Set<T>转换为List<T>的最简洁的方法
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用Java重命名文件
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- Java Regex捕获组
- Openssl不被视为内部或外部命令