web-dev-qa-db-fra.com

Comment "imprimer" une durée en Java?

Quelqu'un connaît-il une bibliothèque Java qui peut imprimer un nombre en millisecondes de la même manière que C #?

Par exemple, 123456 ms de long seront imprimés en 4d1h3m5s.

72
phatmanace

Joda Time a une assez bonne façon de le faire en utilisant un PeriodFormatterBuilder .

Quick Win: 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();
String formatted = formatter.print(duration.toPeriod());
System.out.println(formatted);
86
Rob Hruska

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

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

Le résultat ressemblera à:

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

Si vous ne voulez pas d'espaces entre eux, supprimez simplement replaceAll.

49
lucasls

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

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

Si ce format n'est pas celui que vous souhaitez, alors PeriodFormatterBuilder vous permet d'assembler des dispositions arbitraires, y compris votre style C # 4d1h3m5s.

10
skaffman

Apache commons-lang fournit une classe utile pour y parvenir également DurationFormatUtils

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

10
noleto

Avec Java 8, vous pouvez également utiliser la méthode toString() de Java.time.Duration pour le formater sans bibliothèques externes en utilisant représentation basée sur les secondes ISO 8601 tel que PT8H6M12.345S.

8
Konrad Höffner

Voici comment vous pouvez le faire en utilisant du 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()); 
6
user678573

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”
4
Nick

Java 9+

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

2 h 1 h 6 min 4 s

4

org.threeten.extra.AmountFormats.wordBased

Le projet ThreeTen-Extra , qui est maintenu par Stephen Colebourne, l'auteur de JSR 310, Java.time , et Joda-Time , a une classe AmountFormats qui fonctionne avec l'heure de date standard Java 8 Des classes. C'est assez verbeux cependant, sans option pour une sortie plus compacte.

Duration d = Duration.ofMinutes(1).plusSeconds(9).plusMillis(86);
System.out.println(AmountFormats.wordBased(d, Locale.getDefault()));

1 minute, 9 seconds and 86 milliseconds

4
Adrian Baker

Une alternative à l'approche constructeur de Joda-Time serait une solution basée sur un modèle . 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<IsoUnit> dur = Duration.of(123456, unit).with(Duration.STD_PERIOD);
String 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 façon utilise la classe net.time4j.PrettyTime (ce qui est également bon pour 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
3
Meno Hochschild

Une version Java 8 basée sur réponse de l'utilisateur67857 :

    private static String humanReadableFormat(Duration duration) {
    return String.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()));
}

... car 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.

3
Torsten