Comment formater une durée en Java? (par exemple format H: MM: SS)

Je voudrais formater une durée en secondes en utilisant un motif comme H: MM: SS. Les utilitaires actuels de Java sont conçus pour formater une heure mais pas une durée.

Si vous utilisez une version de Java antérieure à 8, vous pouvez utiliser Joda Time et PeriodFormatter . Si vous avez vraiment une durée (c.-à-d. Une période de temps écasting, sans référence à un système de calendrier), vous devriez probablement utiliser Duration pour la plupart – vous pouvez alors appeler toPeriod (en spécifiant le PeriodType vous voulez 25 heures devient 1 jour et 1 heure ou non, etc.) pour obtenir une Period que vous pouvez formater.

Si vous utilisez Java 8 ou une version ultérieure: je suggère normalement d’utiliser java.time.Duration pour représenter la durée. Vous pouvez alors appeler getSeconds() ou similaire pour obtenir un entier pour le formatage standard selon la réponse de Bobince si vous en avez besoin – bien que vous devriez faire attention à la situation où la durée est négative. la chaîne de sortie. Donc quelque chose comme:

 public static Ssortingng formatDuration(Duration duration) { long seconds = duration.getSeconds(); long absSeconds = Math.abs(seconds); Ssortingng positive = Ssortingng.format( "%d:%02d:%02d", absSeconds / 3600, (absSeconds % 3600) / 60, absSeconds % 60); return seconds < 0 ? "-" + positive : positive; } 

Le formatage de cette manière est relativement simple, même s'il est agaçant manuellement. Pour parsingr cela devient plus difficile en général ... Vous pouvez toujours utiliser Joda Time même avec Java 8 si vous le souhaitez, bien sûr.

Si vous ne voulez pas faire glisser dans les bibliothèques, il est assez simple de faire vous-même un formateur, ou un raccourci associé, par exemple. nombre entier de secondes s:

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

J’utilise comme exemple:

 DurationFormatUtils.formatDuration(millis, "**H:mm:ss**", true)); 
 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()))); 

Ce sera plus facile avec Java 9. Une Duration n’est toujours pas formatable (ce que je sais), mais les méthodes pour obtenir les heures, les minutes et les secondes sont ajoutées, ce qui rend la tâche plus simple:

  Duration diff = // ...; Ssortingng hms = Ssortingng.format("%d:%02d:%02d", diff.toHoursPart(), diff.toMinutesPart(), diff.toSecondsPart()); 

Ce sera l’une des nouvelles fonctionnalités de Java 7

JSR-310

Voici un autre exemple sur la manière de formater la durée. Notez que cet échantillon affiche à la fois une durée positive et une durée négative.

 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(Ssortingng[] 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()); } } 

Cela peut être un peu piraté, mais c’est une bonne solution si l’on veut accomplir cela en utilisant java.time Java 8:

 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 SsortingngBuilder().append(field.toSsortingng()).toSsortingng()); return temporal.getLong(field)-BASE_TEMPORAL.getLong(field); } public Duration getDuration() { return duration; } @Override public Ssortingng toSsortingng() { 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(); } 

Ceci est une option de travail.

 public static Ssortingng 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()); Ssortingng output = fTime.format(df); System.out.println(output); return output; } 

Appeler la méthode avec

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

Produit quelque chose comme:

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

Que diriez-vous de la fonction suivante, qui renvoie soit + H: MM: SS ou + H: MM: SS.sss

 public static Ssortingng 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 Ssortingng.format("%02d:%02d:%02d.%03d", hr, min, sec, ms); } else { return Ssortingng.format("%02d:%02d:%02d", hr, min, sec ); } } 
 Ssortingng duration(Temporal from, Temporal to) { final SsortingngBuilder builder = new SsortingngBuilder(); 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.toSsortingng().sortingm(); } 

Ma bibliothèque Time4J propose une solution basée sur des modèles (similaire à Apache DurationFormatUtils , mais plus flexible):

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

Ce code montre les fonctionnalités permettant de gérer les dépassements d’heure et la gestion des signes, voir également l’API de duration-formatter basée sur le modèle .

en scala, aucune bibliothèque nécessaire:

 def prettyDuration(str:List[Ssortingng],seconds:Long):List[Ssortingng]={ 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[Ssortingng], 12345).mkSsortingng("") 

Cette réponse utilise uniquement les méthodes Duration et fonctionne avec Java 8:

 public static Ssortingng 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,"); }