我想使用像H:MM:SS这样的模式来格式化持续时间(以秒为单位)。 java中的当前实用程序旨在格式化时间而不是持续时间。
答案 0 :(得分:179)
如果您不想在库中拖动,那么使用Formatter或相关的快捷方式就足够了。给定整数秒数:
String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60));
答案 1 :(得分:84)
我像这样使用Apache common DurationFormatUtils:
DurationFormatUtils.formatDuration(millis, "**H:mm:ss**", true);
答案 2 :(得分:74)
如果您使用的是8之前的Java版本,则可以使用Joda Time和PeriodFormatter
。如果你确实有一个持续时间(即没有参考日历系统的时间),那么你应该大部分时间都在使用Duration
- 然后你可以调用toPeriod
(指定您要反映的PeriodType
是否需要25小时变为1天和1小时等,以获得可以格式化的Period
。
如果您使用的是Java 8或更高版本:我通常建议您使用java.time.Duration
来表示持续时间。然后,如果需要,您可以调用getSeconds()
或类似内容来获取标准字符串格式的整数,以便根据bobince的答案 - 尽管您应该注意持续时间为负的情况,因为您可能需要输出字符串中的单个负号。如下所示:
public static String formatDuration(Duration duration) {
long seconds = duration.getSeconds();
long absSeconds = Math.abs(seconds);
String positive = String.format(
"%d:%02d:%02d",
absSeconds / 3600,
(absSeconds % 3600) / 60,
absSeconds % 60);
return seconds < 0 ? "-" + positive : positive;
}
格式化这种方式合理简单,如果烦人的手动。对于解析而言,一般来说它变得更难:如果你愿意,你仍然可以使用Joda Time,即使你也可以使用它。
答案 3 :(得分:24)
long duration = 4 * 60 * 60 * 1000;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault());
log.info("Duration: " + sdf.format(new Date(duration - TimeZone.getDefault().getRawOffset())));
答案 4 :(得分:18)
使用Java 9会更容易。Duration
仍然不是可格式化的(我所知道的),但是添加了获取小时,分钟和秒的方法,这使得任务更加简单:
Duration diff = // ...;
String hms = String.format("%d:%02d:%02d",
diff.toHoursPart(),
diff.toMinutesPart(),
diff.toSecondsPart());
答案 5 :(得分:7)
这可能有点像hacky,但是如果有人希望使用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();
}
答案 6 :(得分:6)
这将成为java 7中的新功能之一
答案 7 :(得分:6)
以下是另一个如何格式化持续时间的示例。 请注意,此示例将正和负持续时间显示为正持续时间。
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());
}
}
答案 8 :(得分:3)
这是一个可行的选择。
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
答案 9 :(得分:2)
以下函数如何返回 + H:MM:SS 要么 + H:MM:SS.SSS
public static String formatInterval(final long interval, boolean millisecs )
{
final long hr = TimeUnit.MILLISECONDS.toHours(interval);
final long min = TimeUnit.MILLISECONDS.toMinutes(interval) %60;
final long sec = TimeUnit.MILLISECONDS.toSeconds(interval) %60;
final long ms = TimeUnit.MILLISECONDS.toMillis(interval) %1000;
if( millisecs ) {
return String.format("%02d:%02d:%02d.%03d", hr, min, sec, ms);
} else {
return String.format("%02d:%02d:%02d", hr, min, sec );
}
}
答案 10 :(得分:2)
还有另一种方法可以为 java8 制作它
> (cons* '())
()
> (cons* 'a)
a
> (cons* 'a 'b 'c 'd)
(a b c . d)
> (cons* 'a 'b '(c d))
(a b c d)
答案 11 :(得分:2)
您可以使用 java.time.Duration
,它以 ISO-8601 standards 为模型,并作为 JSR-310 implementation 的一部分与 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。
答案 12 :(得分:1)
此答案仅使用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+" jours,")+
(hours == 0?"":hours+" heures,")+
(minutes == 0?"":minutes+" minutes,")+
(seconds == 0?"":seconds+" secondes,");
}
答案 13 :(得分:1)
使用此功能
private static String strDuration(long duration) {
int ms, s, m, h, d;
double dec;
double time = duration * 1.0;
time = (time / 1000.0);
dec = time % 1;
time = time - dec;
ms = (int)(dec * 1000);
time = (time / 60.0);
dec = time % 1;
time = time - dec;
s = (int)(dec * 60);
time = (time / 60.0);
dec = time % 1;
time = time - dec;
m = (int)(dec * 60);
time = (time / 24.0);
dec = time % 1;
time = time - dec;
h = (int)(dec * 24);
d = (int)time;
return (String.format("%d d - %02d:%02d:%02d.%03d", d, h, m, s, ms));
}
答案 14 :(得分:1)
我不确定您是否要这样做,但请检查此Android帮助器类
import android.text.format.DateUtils
例如:DateUtils.formatElapsedTime()
答案 15 :(得分:1)
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();
}
答案 16 :(得分:0)
在Scala中,以YourBestBet的解决方案为基础,但进行了简化:
def prettyDuration(seconds: Long): List[String] = seconds match {
case t if t < 60 => List(s"${t} seconds")
case t if t < 3600 => s"${t / 60} minutes" :: prettyDuration(t % 60)
case t if t < 3600*24 => s"${t / 3600} hours" :: prettyDuration(t % 3600)
case t => s"${t / (3600*24)} days" :: prettyDuration(t % (3600*24))
}
val dur = prettyDuration(12345).mkString(", ") // => 3 hours, 25 minutes, 45 seconds
答案 17 :(得分:0)
至少在少于24小时的时间里,有一种相当简单且(IMO)优雅的方法:
DateTimeFormatter.ISO_LOCAL_TIME.format(value.addTo(LocalTime.of(0, 0)))
格式化程序需要一个时态对象进行格式化,因此您可以通过将持续时间添加到本地时间00:00(即午夜)来创建格式化对象。这将为您提供一个LocalTime,表示从午夜到该时间的持续时间,然后可以使用标准的HH:mm:ss表示法轻松对其进行格式化。这样的好处是不需要外部库,而是使用java.time库进行计算,而不是手动计算小时,分钟和秒。
答案 18 :(得分:0)
在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.format
样式的字符串内插器(正是这样才能使$
代码注入工作)
给定输出1 14:06:32.583
,插入的f
等效于String.format("1 %02d:%02d:%02d.%03d", 14, 6, 32, 583)
答案 19 :(得分:0)
我的图书馆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
此代码演示了处理小时溢出和符号处理的功能,另请参阅duration-formatter based on pattern的API。
答案 20 :(得分:0)
看看所有这些计算,大多数单位(小时、分钟等)都有一个 .toFooPart()
方便的方法。
例如
Duration.ofMinutes(110L).toMinutesPart() == 50
读取:到父单位的下一个值(小时)所经过的分钟数。
答案 21 :(得分:-1)
,不需要库:
def prettyDuration(str:List[String],seconds:Long):List[String]={
seconds match {
case t if t < 60 => str:::List(s"${t} seconds")
case t if (t >= 60 && t< 3600 ) => List(s"${t / 60} minutes"):::prettyDuration(str, t%60)
case t if (t >= 3600 && t< 3600*24 ) => List(s"${t / 3600} hours"):::prettyDuration(str, t%3600)
case t if (t>= 3600*24 ) => List(s"${t / (3600*24)} days"):::prettyDuration(str, t%(3600*24))
}
}
val dur = prettyDuration(List.empty[String], 12345).mkString("")
答案 22 :(得分:-1)
我没有看到这个,所以我想添加它:
Date started=new Date();
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
task
long duration=new Date().getTime()-started.getTime();
System.out.println(format.format(new Date(duration));
它只能工作24小时,但这就是我通常想要的持续时间。