在Java中将时间间隔字符串转换为毫秒数

6

如果这个问题已经讨论过了,我很抱歉。

我有一个字符串表示的剪辑时长:

00:10:17

我希望把这个字符串转换成毫秒值。(对于上面的字符串,基本上是617000)

有没有API可以在一两步内完成此操作。其中一种基本方法是将字符串拆分,然后添加分钟、秒钟和小时。

但是有没有更简短的方法呢?

谢谢。


无日期,只有持续时间(HH:MM:SS)。 - Sunny
1
类似问题:[Java:如何将字符串(HH:MM:SS)转换为持续时间?](https://dev59.com/S2sy5IYBdhLWcg3w3h6I) - Basil Bourque
8个回答

12

java.time.Duration

使用 Duration 类。
Duration.between( 
    LocalTime.MIN , 
    LocalTime.parse( "00:10:17" ) 
).toMillis()

毫秒:617000

在IdeOne.com上查看代码实现

查看我的答案我的答案以获取有关DurationLocalTime和java.time的更多解释。

注意:在将java.time对象中可能存在的纳秒值转换为所需的毫秒时,请注意可能会丢失数据。


10

以下是一种自己编写的可能方法(假设始终具有相同的源格式)

String source = "00:10:17";
String[] tokens = source.split(":");
int secondsToMs = Integer.parseInt(tokens[2]) * 1000;
int minutesToMs = Integer.parseInt(tokens[1]) * 60000;
int hoursToMs = Integer.parseInt(tokens[0]) * 3600000;
long total = secondsToMs + minutesToMs + hoursToMs;

@Sunny 感谢您的接受(但是assylias的答案有更简洁的解决方案,所以请使用assylias的解决方案)。 - Simon Dorociak

9
您可以手动解析它:
String s = "00:10:17";
String[] data = s.split(":");

int hours  = Integer.parseInt(data[0]);
int minutes = Integer.parseInt(data[1]);
int seconds = Integer.parseInt(data[2]);

int time = seconds + 60 * minutes + 3600 * hours;
System.out.println("time in millis = " + TimeUnit.MILLISECONDS.convert(time, TimeUnit.SECONDS));

+1 assylias 对于 TimeUnit.MILLISECONDS.convert(time, TimeUnit.SECONDS));。哇:]我真的不知道那个。很好的补充。 - Simon Dorociak
1
@Sajmon 我本来也可以用它来计算时间,但有点懒——不过承认它确实很啰嗦;-) - assylias

1
你可以使用java.time.Duration,它是基于ISO-8601标准建模的,并作为JSR-310实现的一部分在Java-8中引入。
import java.time.Duration;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String strDuration = "00:10:17";
        int[] parts = Arrays.stream(strDuration.split(":"))
                            .mapToInt(Integer::parseInt)
                            .toArray();

        Duration duration = Duration.ZERO;
        long millis = 0;

        if (parts.length == 3) {
            millis = duration.plusHours(parts[0])
                                .plusMinutes(parts[1])
                                .plusSeconds(parts[2])
                                .toMillis();
        }

        System.out.println(millis);
    }
}

输出:

617000

注意: 我使用了Stream API将String[]转换为int[]。您也可以不使用Stream API进行转换,方法如下:

String strDuration = "00:10:17";
String[] strParts = strDuration.split(":");
int[] parts = new int[strParts.length];
for (int i = 0; i < strParts.length; i++) {
    parts[i] = Integer.parseInt(strParts[i]);
}

或者,您可以在添加到Duration时分析这些部分,如下所示:

import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        String strDuration = "00:10:17";
        String[] parts = strDuration.split(":");

        Duration duration = Duration.ZERO;
        long millis = 0;

        if (parts.length == 3) {
            millis = duration.plusHours(Integer.parseInt(parts[0]))
                                .plusMinutes(Integer.parseInt(parts[1]))
                                .plusSeconds(Integer.parseInt(parts[2]))
                                .toMillis();
        }

        System.out.println(millis);
    }
}

输出:

617000

Trail: Date Time了解现代日期时间API。

  1. 如果由于任何原因,您必须坚持使用Java 6或Java 7,则可以使用ThreeTen-Backport将大多数java.time功能回溯到Java 6和7。
  2. 如果您正在为Android项目工作,并且您的Android API级别仍不符合Java-8,请查看Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

一些关于Java Stream API的绝佳教程:

  1. 使用Java SE 8 Streams处理数据,第1部分
  2. 第2部分:使用Java SE 8 Streams处理数据
  3. 课程:集合操作
  4. 简化操作

0

一个重复的问题(底部链接)询问了一个没有秒的字符串,只有HH:MM,例如25:25,使用Java 7。我仍然推荐使用java.time的Duration类,这是现代Java日期和时间API。java.time已经向后兼容到Java 6和7。有许多方法可以使用它。很容易将Basil Bourque和Live and Let Live的好答案之一适应到没有秒的字符串上。我正在展示另一种方法。

    String durationString = "25:25"; // HH:MM, so 25 hours 25 minutes
    String isoDurationString
            = durationString.replaceFirst("^(\\d+):(\\d{2})$", "PT$1H$2M");
    long durationMilliseconds = Duration.parse(isoDurationString).toMillis();
    System.out.format(Locale.US, "%,d milliseconds%n", durationMilliseconds);

在Java 1.7.0_67上运行的输出:

91,500,000毫秒

Duration.parse()只接受ISO 8601格式,例如PT25T25M。表示25小时25分钟的时间段。所以,我使用正则表达式将您提供的字符串转换为所需的格式。

这种方法的一个限制(与其他一些方法共享的限制)是它提供了较差的验证。我们希望拒绝大于59的分钟数,但 Duration.parse()接受它们。

问题:您是否声称它适用于Java 1.7?

确实如此,java.time只需要至少Java 1.6

  • 在Java 8及更高版本以及新的Android设备(API级别26以上)中,现代API已内置。
  • 在非Android Java 6和7中,获取ThreeTen Backport,即现代类的后移版本(JSR 310的ThreeTen;请参见底部链接)。
  • 在旧版Android上,可以使用desugaring或ThreeTen Backport的Android版。它被称为ThreeTenABP。在后一种情况下,请确保从org.threeten.bp子包导入日期和时间类。

链接


0
创建一个适当的DateFormat实例。使用parse()方法获取Date。在Date对象上使用getTime()获取毫秒数。
您可以在这里进行检查。
我刚刚测试了它,如下所示:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class Test {        
    public static void main(String[] args) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

        String inputString = "00:10:17";

        Date date = sdf .parse(inputString);// .parse("1970-01-01" + inputString);
        System.out.println("in milliseconds: " + date.getTime());        
    }
}

是的,它不起作用,因为它会给出从现在到那个特定时间的毫秒数。 - Sunny
“Trick”让链接起作用的方法是将日期设置为1970年1月1日。如果不这样做,您将得到错误的结果。 - assylias

0

FYI,Joda-Time 项目现已进入维护模式,团队建议迁移到 java.time 类。 - Basil Bourque

0

无论持续时间包括小时、分钟、秒还是没有,都不重要。

  public static long durationToMillis(String duration) {
    String[] parts = duration.split(":");
    long result = 0;
    for (int i = parts.length - 1, j = 1000; i >= 0; i--, j *= 60) {
        try {
            result += Integer.parseInt(parts[i]) * j;
        } catch (NumberFormatException ignored) {
        }
    }
    return result;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接