Comment puis-je «imprimer» une durée en Java?

Est-ce que quelqu’un connaît une bibliothèque Java capable d’imprimer un nombre en millisecondes de la même manière que C #?

Par exemple, une longueur de 123456 ms serait imprimée à 4d1h3m5s.

Joda Time a un très bon moyen de le faire en utilisant PeriodFormatterBuilder .

Win rapide: PeriodFormat.getDefault().print(duration.toPeriod());

par exemple

 //import org.joda.time.format.PeriodFormatter; //import org.joda.time.format.PeriodFormatterBuilder; //import org.joda.time.Duration; Duration duration = new Duration(123456); // in milliseconds PeriodFormatter formatter = new PeriodFormatterBuilder() .appendDays() .appendSuffix("d") .appendHours() .appendSuffix("h") .appendMinutes() .appendSuffix("m") .appendSeconds() .appendSuffix("s") .toFormatter(); Ssortingng formatted = formatter.print(duration.toPeriod()); System.out.println(formatted); 

J’ai construit une solution simple, en utilisant Duration.toSsortingng() Java 8 et un peu de regex:

 public static Ssortingng humanReadableFormat(Duration duration) { return duration.toSsortingng() .subssortingng(2) .replaceAll("(\\d[HMS])(?!$)", "$1 ") .toLowerCase(); } 

Le résultat ressemblera à ceci:

 - 5h - 7h 15m - 6h 50m 15s - 2h 5s - 0.1s 

Si vous ne voulez pas d’espace, supprimez simplement replaceAll .

JodaTime a une classe Period qui peut représenter ces quantités et peut être rendue (via IsoPeriodFormat ) au format ISO8601 , par exemple PT4D1H3M5S , par exemple

 Period period = new Period(millis); Ssortingng formatted = ISOPeriodFormat.standard().print(period); 

Si ce format n’est pas celui que vous voulez, PeriodFormatterBuilder vous permet d’assembler des mises en page arbitraires, y compris votre style C # 4d1h3m5s .

Avec Java 8, vous pouvez également utiliser la toSsortingng() de java.time.Duration pour la formater sans bibliothèques externes en utilisant une représentation basée sur ISO 8601 secondes telle que PT8H6M12.345S.

Apache commons-lang fournit une classe utile pour que cela se fasse aussi bien. DurationFormatUtils

eg DurationFormatUtils.formatDurationHMS( 15362 * 1000 ) ) => 4: 16: 02.000 (H: m: s.millis) DurationFormatUtils.formatDurationISO( 15362 * 1000 ) ) => P0Y0M0DT4H16M2.000S, cf. ISO8601

Voici comment procéder en utilisant un code JDK pur:

 import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; long diffTime = 215081000L; Duration duration = DatatypeFactory.newInstance().newDuration(diffTime); System.out.printf("%02d:%02d:%02d", duration.getDays() * 24 + duration.getHours(), duration.getMinutes(), duration.getSeconds()); 

Je me rends compte que cela pourrait ne pas correspondre exactement à votre cas d’utilisation, mais PrettyTime pourrait être utile ici.

 PrettyTime p = new PrettyTime(); System.out.println(p.format(new Date())); //prints: “right now” System.out.println(p.format(new Date(1000*60*10))); //prints: “10 minutes from now” 

Une solution alternative à l’approche constructeur de Joda-Time serait une solution basée sur des modèles . Ceci est offert par ma bibliothèque Time4J . Exemple utilisant la classe Duration.Formatter (ajout de quelques espaces pour plus de lisibilité – la suppression des espaces donnera le style C # souhaité):

 IsoUnit unit = ClockUnit.MILLIS; Duration dur = Duration.of(123456, unit).with(Duration.STD_PERIOD); Ssortingng s = Duration.Formatter.ofPattern("D'd' h'h' m'm' s.fff's'").format(dur); System.out.println(s); // output: 0d 0h 2m 3.456s 

Une autre méthode consiste à utiliser la classe net.time4j.PrettyTime (qui convient également à la sortie localisée et à l’impression des temps relatifs):

 s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.NARROW); System.out.println(s); // output: 2m 3s 456ms 

Java 9

 Duration d1 = Duration.ofDays(0); d1 = d1.plusHours(47); d1 = d1.plusMinutes(124); d1 = d1.plusSeconds(124); System.out.println(Ssortingng.format("%sd %sh %sm %ss", d1.toDaysPart(), d1.toHoursPart(), d1.toMinutesPart(), d1.toSecondsPart())); 

2 j 1h 6m 4s

Une version de Java 8 basée sur la réponse de user678573 :

  private static Ssortingng humanReadableFormat(Duration duration) { return Ssortingng.format("%s days and %sh %sm %ss", duration.toDays(), duration.toHours() - TimeUnit.DAYS.toHours(duration.toDays()), duration.toMinutes() - TimeUnit.HOURS.toMinutes(duration.toHours()), duration.getSeconds() - TimeUnit.MINUTES.toSeconds(duration.toMinutes())); } 

… puisqu’il n’y a pas de PeriodFormatter dans Java 8 et aucune méthode comme getHours, getMinutes, …

Je serais heureux de voir une meilleure version pour Java 8.