Est-ce que quelqu'un connaît une bibliothèque Java qui peut assez imprimer un nombre en millisecondes de la même manière que C #?
Par exemple, 123456 ms en tant que long serait imprimé sous la forme 4d1h3m5s.
Est-ce que quelqu'un connaît une bibliothèque Java qui peut assez imprimer un nombre en millisecondes de la même manière que C #?
Par exemple, 123456 ms en tant que long serait imprimé sous la forme 4d1h3m5s.
%
et /
pour diviser le nombre en parties. Presque plus facile que certaines des réponses proposées.
/
et %
.
Réponses:
Heure Joda a un très bon moyen de le faire en utilisant un PeriodFormatterBuilder .
Victoire 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();
String formatted = formatter.print(duration.toPeriod());
System.out.println(formatted);
PeriodType.daysTime()
ou .standard()
n'a pas aidé
J'ai construit une solution simple, en utilisant Java 8 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 les deux, supprimez simplement replaceAll
.
Duration::toString
est formatée selon la norme ISO 8601 bien définie et bien utilisée .
.replaceAll("\\.\\d+", "")
avant l'appel à toLowerCase()
.
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
JodaTime a une Period
classe qui peut représenter de telles quantités, et peut être rendue (via IsoPeriodFormat
) au format ISO8601 , par PT4D1H3M5S
exemple
Period period = new Period(millis);
String formatted = ISOPeriodFormat.standard().print(period);
Si ce format n'est pas celui que vous souhaitez, PeriodFormatterBuilder
vous permet d'assembler des mises en page arbitraires, y compris votre style C # 4d1h3m5s
.
new Period(millis).toString()
utilise le ISOPeriodFormat.standard()
par défaut.
Avec Java 8, vous pouvez également utiliser la toString()
méthode de java.time.Duration
pour le formater sans bibliothèques externes en utilisant une représentation basée sur ISO 8601 secondes telle 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());
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 AmountFormats
classe qui fonctionne avec les classes de date standard Java 8. 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
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 j 1h 6m 4s
Une 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<IsoUnit> dur = // normalized duration with multiple components
Duration.of(123456, unit).with(Duration.STD_PERIOD);
Duration.Formatter<IsoUnit> f = // create formatter/parser with optional millis
Duration.Formatter.ofPattern("D'd' h'h' m'm' s[.fff]'s'");
System.out.println(f.format(dur)); // output: 0d 0h 2m 3.456s
Ce formateur peut également imprimer des durées de java.time
-API (cependant, les fonctionnalités de normalisation de ce type sont moins puissantes):
System.out.println(f.format(java.time.Duration.ofMillis(123456))); // output: 0d 0h 2m 3.456s
L'espoir de l'OP selon lequel "123456 ms en tant que long serait imprimé comme 4d1h3m5s" est calculé d'une manière manifestement erronée. Je suppose que la négligence est une raison. Le même formateur de durée défini ci-dessus peut également être utilisé comme analyseur. Le code suivant montre que "4d1h3m5s" correspond plutôt à 349385000 = 1000 * (4 * 86400 + 1 * 3600 + 3 * 60 + 5)
:
System.out.println(
f.parse("4d 1h 3m 5s")
.toClockPeriodWithDaysAs24Hours()
.with(unit.only())
.getPartialAmount(unit)); // 349385000
Une autre méthode consiste à utiliser la classe net.time4j.PrettyTime
(qui est également utile pour la sortie localisée et l'impression des heures relatives telles que "hier", "dimanche prochain", "il y a 4 jours", etc.):
String s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.NARROW);
System.out.println(s); // output: 2m 3s 456ms
s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.WIDE);
System.out.println(s); // output: 2 minutes, 3 seconds, and 456 milliseconds
s = PrettyTime.of(Locale.UK).print(dur, TextWidth.WIDE);
System.out.println(s); // output: 2 minutes, 3 seconds and 456 milliseconds
La largeur du texte contrôle si les abréviations sont utilisées ou non. Le format de la liste peut également être contrôlé en choisissant les paramètres régionaux appropriés. Par exemple, l'anglais standard utilise la virgule Oxform, contrairement au Royaume-Uni. La dernière version v5.5 de Time4J prend en charge plus de 90 langues et utilise des traductions basées sur le référentiel CLDR (une norme de l'industrie).
Une version Java 8 basée sur la réponse de user678573 :
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.
Je me rends compte que cela peut ne pas correspondre exactement à votre cas d'utilisation, mais PrettyTime peut ê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”
Duration
défini dans la norme sensible, ISO 8601 :PnYnMnDTnHnMnS
oùP
signifie "Période" et marque le début,T
sépare la partie date de la partie heure, et entre les occurrences facultatives d'un nombre avec un seul -abréviation de lettre. Par exemple,PT4H30M
= quatre heures et demie.