我想用H:MM:SS这样的模式格式化持续时间(以秒为单位).java中的当前实用程序旨在格式化时间而不是持续时间.
如果你不想在库中拖动,那么使用Formatter或相关的快捷方式就足够了.给定整数秒数s:
String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60));
我使用Apache common的DurationFormatUtils,如下所示:
DurationFormatUtils.formatDuration(millis, "**H:mm:ss**", true);
如果您使用的是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甚至Java 8.
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())));
使用Java 9会更容易.Duration
但仍然不是可格式化的(我所知道的),但是添加了获取小时,分钟和秒的方法,这使得任务变得更加简单:
Duration diff = // ...; String hms = String.format("%d:%02d:%02d", diff.toHoursPart(), diff.toMinutesPart(), diff.toSecondsPart());
这可能是一种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(); }
这将成为java 7中的新功能之一
JSR-310
这是另一个如何格式化持续时间的示例.请注意,此示例将正和负持续时间显示为正持续时间.
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()); } }
此答案仅使用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,"); }