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.
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);
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
.
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
.
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
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.
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());
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”
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
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
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
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.