web-dev-qa-db-fra.com

Formatage d'une durée en Java 8/jsr310

Je suis en train de faire la transition d'un projet de Joda-Time vers les bibliothèques de temps natives de Java8 et j'ai rencontré un problème. Je suis incapable de trouver un formateur pour Durée. J'aimerais avoir un format de chaîne personnalisé, par exemple, HHH + MM, où une durée de 75 heures et 15 minutes serait au format "75 + 15". Cela était facile à faire avec Joda-Time en convertissant en période et en utilisant un PeriodFormatter, mais je n'ai pas pu trouver ce type de classe en Java8. Est-ce que je manque quelque chose?

35
Chad Lowe

Il n'y a pas de formateur de période/durée dans jsr-310, différent de JodaTime. Toutes les fonctionnalités de JodaTime n'étaient pas portées sur JSR-310 (par exemple, pas également PeriodType). Et inversement, JSR-310 possède certaines fonctionnalités qui ne sont pas disponibles dans JodaTime (par exemple, les numéros de jours de semaine localisés ou l’approche de modèle de stratégie avec des ajusteurs).

Il se peut que Java 9 introduise une sorte de formatage de période intégré (lisez quelque chose à ce sujet chez S. Colebourne).

Conclusion: JSR-310 et JodaTime ne sont pas totalement compatibles, ce qui nécessite beaucoup de travail. Je ne serais pas aussi féru de migration dès que possible. Avez-vous besoin de fonctionnalités spéciales de JSR-310 qui ne sont pas proposées par JodaTime?

Remarque supplémentaire: vous devez également savoir que la période joda (qui inclut toutes les unités, en années) n'est pas totalement compatible avec jsr310-period (seulement années, mois, jours) ou jsr310-duration secondes et fractions de secondes).

19
Meno Hochschild

Java 9 et versions ultérieures: méthodes Duration::to…Part

En Java 9, la Duration class a gagné de nouvelles méthodes to…Part pour renvoyer les différentes parties de jours, heures, minutes, secondes, millisecondes/nanosecondes. Voir ceci pré-release code source OpenJDK .

Étant donné une durée de 49H30M20.123S…

  • toNanosPart() = 123000000
  • toMillisPart() = 123
  • toSecondsPart() = 20
  • toMinutesPart() = 30
  • toHoursPart() = 1
  • toDaysPart() = 2 

Rappelez-vous que «jours» signifie ici des tranches de 24 heures, en ignorant les dates d'un calendrier. Si vous vous souciez des dates, utilisez plutôt Period class.

Je ne sais pas si d'autres fonctionnalités de formatage sont ajoutées. Mais au moins, vous pourrez générer plus facilement vos propres chaînes à partir de nombres obtenus via ces nouvelles méthodes de lecture.

Java 8

Curieusement, aucune méthode getter pratique pour ces valeurs n’était incluse dans la première édition de Java.time en Java 8. L’un des rares oublis dans la conception par ailleurs excellente du framework Java.time.

Voir la question connexe: Pourquoi ne puis-je pas obtenir une durée en minutes ou en heures en Java.time? .

22
Basil Bourque

Il n'y a pas de méthode intégrée, mais vous pouvez accéder au nombre d'heures/minutes sans avoir à les calculer manuellement. Votre format spécifique pourrait ressembler à:

Duration d = Duration.of(75, HOURS).plusMinutes(15);
long hours = d.toHours(); //75
long minutes = d.minusHours(hours).toMinutes(); //15
String HH_PLUS_MM = hours + "+" + minutes; //75+15
System.out.println(HH_PLUS_MM);

Si la durée est inférieure à 24 heures, vous pouvez également utiliser cette astuce:

String hhPlusMm = LocalTime.MIDNIGHT.plus(d).format(DateTimeFormatter.ofPattern("HH+mm"));
18
assylias

vous pouvez utiliser le DurationFormatUtils de commons-lang3-time (vous devez utiliser "mm" pour les minutes car le format est le même que dans SimpleDateFormat): DurationFormatUtils.formatDuration(interval.toMillis(), "HHH+mm")

Malheureusement, je n’ai trouvé aucun moyen d’exclure des pièces vides, car dans mon cas, les jours ou les heures pouvaient être égaux à 0, je devais donc toujours lancer les miens.

Mise à jour: j'ai ouvert un problème à ce sujet sur Apache commons.lang.time.DurationFormatUtils JIRA .

7
Gregor

Je sais que c'est une vieille question mais j'ai récemment rencontré la même chose. Il y a vraiment devrait une meilleure solution que celle-ci, mais cela a fonctionné pour moi:

public static String millisToElapsedTime(long millis){
    DateFormat fmt = new SimpleDateFormat(":mm:ss.SSS");
    fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
    return (millis/3600000/*hours*/)+fmt.format(new Date(millis));
}

Ensuite, vous pouvez ajouter ceci:

public static String durationToElapsedTime(Duration d){
    return millisToElapsedTime(d.toMillis());
}
1
CodeBlind