如何将 Joda 的持续时间转换为 java.time.Duration?
How can I convert a Joda's Duration to a java.time.Duration?
我想将 1d2h3m4s
之类的字符串解析为 java.time.Duration
。我可以使用 joda 的 PeriodFormatter
将字符串解析为 org.joda.time.Duration
,但我不知道如何将其转换为标准 Java8 的 java.time.Duration
。
我必须连接一些已经期望 java.time.Duration
作为输入的 "legacy" 代码,但我想使用 joda 的 parsePeriod
因为 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
的用法。我仍然想要一个 org.joda.time.Period
因为我有更多的解析选项来生成它们,我需要一个 java.time.Period
/java.time.Duration
因为我与其他一些 API/libraries 交互期望 java.time.*
。
那么,有没有办法将 org.joda.time.Duration
转换为 java.time.Duration
?
您可以使用 Period#toStandardSeconds()#getSeconds()
将 PeriodFormatter#parse()
返回的 org.joda.time.Period
转换为秒数。这将为您提供 int
的秒数
然后使用 java.time.Duration.ofSeconds()
从 int
创建一个 java.time.Duration
。
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());
我提供三个选项
- 手动将字符串修改为 ISO 8601 格式,以便
java.time.Duration
可以解析它。
- 通过毫秒数转换。
- 从
joda.time.Duration.toString()
转换。
修改字符串
我个人认为我不想为此依赖 Joda-Time。相反,我会将您的非 ISO 8601 字符串修改为 ISO 8601 格式。
String durationString = "1d1s";
// Convert to ISO 8601 format
String isoString = durationString.replaceFirst("(.*?[Dd])?(.*)", "PT");
java.time.Duration dur = java.time.Duration.parse(isoString);
System.out.println(dur);
输出为:
PT24H1S
我承认正则表达式有点难读。如果字符串中有大写或小写 D
,则 D
之前的所有内容(包括 D
都放在 ISO 字符串中的 T
之前。其他所有内容都放在 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 字符串只是为了解析它感觉很浪费。
我想将 1d2h3m4s
之类的字符串解析为 java.time.Duration
。我可以使用 joda 的 PeriodFormatter
将字符串解析为 org.joda.time.Duration
,但我不知道如何将其转换为标准 Java8 的 java.time.Duration
。
我必须连接一些已经期望 java.time.Duration
作为输入的 "legacy" 代码,但我想使用 joda 的 parsePeriod
因为 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
的用法。我仍然想要一个 org.joda.time.Period
因为我有更多的解析选项来生成它们,我需要一个 java.time.Period
/java.time.Duration
因为我与其他一些 API/libraries 交互期望 java.time.*
。
那么,有没有办法将 org.joda.time.Duration
转换为 java.time.Duration
?
您可以使用 Period#toStandardSeconds()#getSeconds()
将 PeriodFormatter#parse()
返回的 org.joda.time.Period
转换为秒数。这将为您提供 int
然后使用 java.time.Duration.ofSeconds()
从 int
创建一个 java.time.Duration
。
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());
我提供三个选项
- 手动将字符串修改为 ISO 8601 格式,以便
java.time.Duration
可以解析它。 - 通过毫秒数转换。
- 从
joda.time.Duration.toString()
转换。
修改字符串
我个人认为我不想为此依赖 Joda-Time。相反,我会将您的非 ISO 8601 字符串修改为 ISO 8601 格式。
String durationString = "1d1s";
// Convert to ISO 8601 format
String isoString = durationString.replaceFirst("(.*?[Dd])?(.*)", "PT");
java.time.Duration dur = java.time.Duration.parse(isoString);
System.out.println(dur);
输出为:
PT24H1S
我承认正则表达式有点难读。如果字符串中有大写或小写 D
,则 D
之前的所有内容(包括 D
都放在 ISO 字符串中的 T
之前。其他所有内容都放在 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 字符串只是为了解析它感觉很浪费。