Как я могу преобразовать Длительность Joda в java.time.Duration? - PullRequest
2 голосов
/ 31 октября 2019

Я хочу разобрать строку типа 1d2h3m4s в java.time.Duration. Я могу использовать joda PeriodFormatter, чтобы разобрать строку в org.joda.time.Duration, но я не могу понять, как преобразовать это в стандартную Java8 java.time.Duration.

Мне нужно подключиться к некоторому «устаревшему» коду, который уже ожидает java.time.Duration в качестве ввода, но я хочу использовать parsePeriod joda, потому что java.time.Duration.parse() принимает только формат продолжительности ISO-8601 (1d2h3m4sне соответствует длительности ISO-8601)

import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;

...

final PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
        .printZeroNever()
        .appendDays().appendSuffix("d")
        .appendHours().appendSuffix("h")
        .appendMinutes().appendSuffix("m")
        .appendSeconds().appendSuffix("s").toFormatter();

org.joda.time.Duration myduration = periodFormatter.parsePeriod("1d1s").toStandardDuration(); 
java.util.time myduration2 = XXXXX

Имейте в виду, что я не пытаюсь удалить использование org.joda.time.Period из моего кода, как в Converting org.joda.time. Период до java.time.Period . Я все еще хочу иметь org.joda.time.Period, потому что у меня есть больше возможностей разбора для их генерации, и мне нужен java.time.Period / java.time.Duration, потому что я взаимодействую с некоторыми другими API / библиотеками, которые ожидают java.time.*.

Итак, есть ли способ преобразовать org.joda.time.Duration в java.time.Duration?

Ответы [ 2 ]

1 голос
/ 31 октября 2019

Я представляю три варианта

  1. Вручную измените строку в формат ISO 8601, чтобы java.time.Duration мог ее проанализировать.
  2. Преобразовать в счетчик миллисекунд.
  3. Конвертировать из joda.time.Duration.toString().

Изменить строку

Лично я не думаю, что я хотел бы зависеть от Joda-Time для этого. Вместо этого я бы изменил вашу строку, отличную от ISO 8601, в формат ISO 8601.

    String durationString = "1d1s";
    // Convert to ISO 8601 format
    String isoString = durationString.replaceFirst("(.*?[Dd])?(.*)", "P$1T$2");
    java.time.Duration dur = java.time.Duration.parse(isoString);
    System.out.println(dur);

Вывод:

PT24H1S

Я допускаю, чторегулярное выражение немного трудно читать. Если в строке есть прописные или строчные буквы D, все, вплоть до D, включая T в строке ISO. Все остальное ставится после T.

Конвертировать за миллисекунды

Эта идея похожа на идею, приведенную в ответе ecerulm. Я не хотел терять точность в миллисекундах продолжительности Joda-Time, поэтому я полагаюсь на миллисекунды, а не на секунды (я знаю, что для ваших примеров строк это не будет иметь значения).

    final PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
            .printZeroNever()
            .appendDays().appendSuffix("d")
            .appendHours().appendSuffix("h")
            .appendMinutes().appendSuffix("m")
            .appendSeconds().appendSuffix("s").toFormatter();

    org.joda.time.Duration myduration = periodFormatter.parsePeriod("1d1s").toStandardDuration(); 

    java.time.Duration dur = java.time.Duration.ofMillis(myduration.getMillis());

результат такой же, как и раньше.

Преобразовать через строку

    java.time.Duration dur = java.time.Duration.parse(myduration.toString());

Опять результат тот же. Форматирование длительности в строку ISO 8601 только для ее анализа выглядит как пустая трата времени.

0 голосов
/ 31 октября 2019

Вы можете просто преобразовать org.joda.time.Period, возвращаемое PeriodFormatter#parse() в секунды, используя Period#toStandardSeconds()#getSeconds(). Это даст вам количество секунд как int

. Затем используйте java.time.Duration.ofSeconds(), чтобы создать java.time.Duration из этого int.

import org.joda.time.format.PeriodFormatterBuilder
import org.joda.time.format.PeriodFormatter

PeriodFormatter formatter = new PeriodFormatterBuilder()
        .printZeroNever()
        .appendDays().appendSuffix("d")
        .appendHours().appendSuffix("h")
        .appendMinutes().appendSuffix("m")
        .appendSeconds().appendSuffix("s")
        .toFormatter();

Period myPeriod = formatter.parsePeriod("1d2h3m4s");

java.time.Duration myDuration = java.time.Duration.ofSeconds(
        myPeriod.toStandardSeconds().getSeconds());
...