web-dev-qa-db-fra.com

Chaînes de temps d'analyse comme "1h 30min"

Toute personne connaissant une bibliothèque Java capable d'analyser des chaînes de temps telles que "30min", "2h 15min" ou "2d 15h 30min" en millisecondes (ou une sorte d'objet Duration). Joda-Time peut-il faire quelque chose comme ça?

(J'ai une longue méthode laide à maintenir qui effectue une telle analyse et je voudrais m'en débarrasser/la remplacer par quelque chose qui fait un meilleur travail.)

34
Jonik

Vous devrez probablement modifier un peu votre format, mais essayez quelque chose dans ce sens:

PeriodFormatter formatter = new PeriodFormatterBuilder()
    .appendDays().appendSuffix("d ")
    .appendHours().appendSuffix("h ")
    .appendMinutes().appendSuffix("min")
    .toFormatter();

Period p = formatter.parsePeriod("2d 5h 30min");

notez qu'il existe une appendSuffix qui prend un paramètre variants si vous devez le rendre plus flexible.

Update : Joda Time a depuis ajouté Period.toStandardDuration() , et à partir de là, vous pouvez utiliser getStandardSeconds() pour obtenir le temps écoulé en secondes sous la forme d'une long.

Si vous utilisez une ancienne version sans ces méthodes, vous pouvez toujours calculer vous-même un horodatage en prenant la norme 24/h dans une journée, 60 min/h, etc. (Dans ce cas, utilisez les constantes de la classe DateTimeConstants pour éviter le besoin de nombres magiques.)

32
Brad Mace

L'analyse de la durée est maintenant incluse dans Java 8 . Utilisez le format standard ISO 8601 avec Duration.parse .

Duration d = Duration.parse("PT1H30M")

Vous pouvez convertir cette durée en longueur totale en millisecondes. Attention, Duration a une résolution de nanosecondes. Vous risquez donc une perte de données allant de nanosecondes à millisecondes .

long milliseconds = d.toMillis();

Le format est légèrement différent de ce que vous décrivez, mais pourrait être facilement traduit de l’un à l’autre.

24
Andrejs

Je voulais rendre le jour, l'heure et les minutes facultatifs et cela semble fonctionner. Notez que les appels appendSuffix () n'ont pas d'espace après le caractère.

Utiliser Joda 2.3.

PeriodParser parser = new PeriodFormatterBuilder()
        .appendDays().appendSuffix("d").appendSeparatorIfFieldsAfter(" ")
        .appendHours().appendSuffix("h").appendSeparatorIfFieldsAfter(" ")
        .appendMinutes().appendSuffix("min")
        .toParser();

Le code ci-dessus passe ces tests.

@Test
public void testConvert() {
    DurationConverter c = new DurationConverter();

    Duration d;
    Duration expected;

    d = c.convert("1d");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardDays(1),1);
    assertEquals(d, expected);

    d = c.convert("1d 1h 1min");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardDays(1),1)
            .withDurationAdded(Duration.standardHours(1),1)
            .withDurationAdded(Duration.standardMinutes(1),1);
    assertEquals(d, expected);


    d = c.convert("1h 1min");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardHours(1),1)
            .withDurationAdded(Duration.standardMinutes(1),1);
    assertEquals(d, expected);

    d = c.convert("1h");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardHours(1),1);
    assertEquals(d, expected);

    d = c.convert("1min");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardMinutes(1),1);
    assertEquals(d, expected);

}
14
Victor

Non, Joda ne prend par défaut que des durées, des intervalles instantanés et des objets. Pour ce dernier, il accepte des éléments tels que les dates ou le format ISOSOAP. Vous pouvez ajouter ici votre propre convertisseur pour la classe Duration, ce qui cacherait tout votre code laid.

0
MJB