我建议使用java.time.Duration,它以ISO-8601 standards 为蓝本,并作为JSR-310 implementation 的一部分与Java-8 一起引入。
根据 ISO-8601 标准,1 天 2 小时的持续时间表示为 P1DT2H,而 2 小时的持续时间表示为 PT2H。将字符串转换为 ISO-8601 格式后,您可以使用 Duration#parse 方法对其进行解析。请注意(感谢 Ole V.V. 提供此信息)后缀“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 了解有关 modern date-time API* 的更多信息。
regex的解释:
-
(?:: 非捕获组开始
-
(?:: 非捕获组开始
-
(?:: 非捕获组开始
-
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 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。