我建议使用java.time.Duration
它以ISO-8601 标准为模型,并作为JSR-310 实现的一部分与Java-8一起引入。
根据 ISO-8601 标准,1 天 2 小时的持续时间表示为 P1DT2H,而 2 小时的持续时间表示为 PT2H。将您的字符串转换为 ISO-8601 格式后,您可以使用该Duration#parse
方法对其进行解析。请注意(感谢 Ole VV 提供此信息)后缀“D”、“H”、“M”和“S”表示天、小时、分钟和秒,可以大写或小写。
演示:
import java.time.Duration;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// Test
Stream.of(
"98d 01h 23m 45s",
"01d 02h 03m 04s",
"02h 03m 04s",
"03m 04s",
"04s"
).forEach(s -> System.out.println(durationMillis(s)));
}
static long durationMillis(String s) {
if (Pattern.compile("\\d+d\\s").matcher(s).find()) {
int idxSpace = s.indexOf(" ");
s = "P" + s.substring(0, idxSpace) + "T" + s.substring(idxSpace + 1);
} else
s = "PT" + s;
s = s.replace(" ", "");
return Duration.parse(s).toMillis();
}
}
示例运行:
8472225000
93784000
7384000
184000
4000
另一种解决方法是检索每个部分的值(天、小时、分钟和秒)并将它们添加到Duration.ZERO
:
static long durationMillis(String s) {
long millis = 0;
Matcher matcher = Pattern.compile("(?:(?:(?:0*(\\d+)d\\s)?0*(\\d+)h\\s)?0*(\\d+)m\\s)?0*(\\d+)s").matcher(s);
if (matcher.find()) {
int days = matcher.group(1) != null ? Integer.parseInt(matcher.group(1)) : 0;
int hours = matcher.group(2) != null ? Integer.parseInt(matcher.group(2)) : 0;
int minutes = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : 0;
int seconds = matcher.group(4) != null ? Integer.parseInt(matcher.group(4)) : 0;
millis = Duration.ZERO.plusDays(days).plusHours(hours).plusMinutes(minutes).plusSeconds(seconds).toMillis();
}
return millis;
}
从Trail: Date Time了解有关现代日期时间 API *的更多信息。
正则表达式的解释:
(?:
: 非捕获组的开始
(?:
: 非捕获组的开始
(?:
: 非捕获组的开始
0*
: 任意数量的零
(\\d+)d\\s
:一个或多个数字(组#1)后跟d
一个空格。
)?
: 非捕获组结束。这?
使它成为可选的。
0*
: 任意数量的零
(\\d+)h\\s
:一个或多个数字(组#2)后跟h
一个空格。
)?
: 非捕获组结束。这?
使它成为可选的。
0*
: 任意数量的零
(\\d+)m\\s
:一个或多个数字(组#3)后跟m
一个空格。
)?
: 非捕获组结束。这?
使它成为可选的。
0*
: 任意数量的零
(\\d+)s
:一位或多位数字(组#4)后跟s
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和 Android API 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring和How to use ThreeTenABP in Android Project。