How can I convert a Joda's Duration to a java.time.Duration?

ecerulm :

I want to parse a string like 1d2h3m4s into a java.time.Duration. I can use a joda's PeriodFormatter to parse the string into a org.joda.time.Duration but I can't figure out how to convert that to a standard Java8's java.time.Duration.

I have to interface to some "legacy" code that already expects java.time.Duration as input, but I want to use joda's parsePeriod because the java.time.Duration.parse() only accepts ISO-8601 duration format (1d2h3m4s is not ISO-8601 duration compliant)

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

Please bear in mind that I'm not trying to remove the usage of org.joda.time.Period from my code like in Converting org.joda.time.Period to java.time.Period. I still want to have a org.joda.time.Period because I have more parsing option to generate those, and I need a java.time.Period/java.time.Duration because I interact with some other API/libraries that expect java.time.*.

So, is there a way to convert a org.joda.time.Duration to a java.time.Duration?

Ole V.V. :

I am presenting three options

  1. Hand modify the string to ISO 8601 format so that java.time.Duration can parse it.
  2. Convert through count of milliseconds.
  3. Convert from joda.time.Duration.toString().

Modify the string

Personally I don’t think I would want to depend in Joda-Time for this. Instead I would modify your non-ISO 8601 string to ISO 8601 format.

    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);

Output is:

PT24H1S

I admit that the regular expression is a bit hard to read. If there is an uppercase or lowercase D in the string, everything up to and including that D is placed before the T in the ISO string. Everything else is placed after the T.

Convert over milliseconds

This is an idea similar to the one in the answer by ecerulm. I didn’t want to lose the millisecond precision of the Joda-Time duration, so I rely of milliseconds rather than seconds (I know that for your example strings it will make no difference).

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

The result is the same as before.

Convert over a string

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

Again the result is the same. Formatting the duration into an ISO 8601 string only to parse it back feels like a waste, though.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324157&siteId=1