如何将 HH:mm:ss.SSS 转换为毫秒?

发布于 2024-12-26 04:01:29 字数 431 浏览 2 评论 0原文

我有一个字符串 00:01:30.500 相当于 90500 毫秒。我尝试使用 SimpleDateFormat 给出包括当前日期在内的毫秒数。我只需要毫秒级的字符串表示形式。我是否必须编写自定义方法来分割并计算毫秒?或者还有其他方法可以做到这一点吗?谢谢。

我尝试过如下:

        String startAfter = "00:01:30.555";
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
        Date date = dateFormat.parse(startAfter);
        System.out.println(date.getTime());

I have a String 00:01:30.500 which is equivalent to 90500 milliseconds. I tried using SimpleDateFormat which give milliseconds including current date. I just need that String representation to milliseconds. Do I have to write custom method, which will split and calculate milliseconds? or Is there any other way to do this? Thanks.

I have tried as follows:

        String startAfter = "00:01:30.555";
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
        Date date = dateFormat.parse(startAfter);
        System.out.println(date.getTime());

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

天气好吗我好吗 2025-01-02 04:01:29

您可以使用 SimpleDateFormat 来完成此操作。你只需要知道两件事。

  1. 所有日期在内部均以 UTC 表示。
  2. .getTime() 返回自 1970-01-01 00:00:00 UTC 以来的毫秒数。
package se.wederbrand.milliseconds;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

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

        String inputString = "00:01:30.500";

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

You can use SimpleDateFormat to do it. You just have to know 2 things.

  1. All dates are internally represented in UTC
  2. .getTime() returns the number of milliseconds since 1970-01-01 00:00:00 UTC.
package se.wederbrand.milliseconds;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

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

        String inputString = "00:01:30.500";

        Date date = sdf.parse("1970-01-01 " + inputString);
        System.out.println("in milliseconds: " + date.getTime());        
    }
}
摘星┃星的人 2025-01-02 04:01:29

如果您想自己解析格式,您可以使用正则表达式轻松完成,例如

private static Pattern pattern = Pattern.compile("(\\d{2}):(\\d{2}):(\\d{2}).(\\d{3})");

public static long dateParseRegExp(String period) {
    Matcher matcher = pattern.matcher(period);
    if (matcher.matches()) {
        return Long.parseLong(matcher.group(1)) * 3600000L 
            + Long.parseLong(matcher.group(2)) * 60000 
            + Long.parseLong(matcher.group(3)) * 1000 
            + Long.parseLong(matcher.group(4)); 
    } else {
        throw new IllegalArgumentException("Invalid format " + period);
    }
}

但是,这种解析非常宽松,会接受 99:99:99.999 并让值溢出。这可能是一个缺点,也可能是一个特点。

If you want to parse the format yourself you could do it easily with a regex such as

private static Pattern pattern = Pattern.compile("(\\d{2}):(\\d{2}):(\\d{2}).(\\d{3})");

public static long dateParseRegExp(String period) {
    Matcher matcher = pattern.matcher(period);
    if (matcher.matches()) {
        return Long.parseLong(matcher.group(1)) * 3600000L 
            + Long.parseLong(matcher.group(2)) * 60000 
            + Long.parseLong(matcher.group(3)) * 1000 
            + Long.parseLong(matcher.group(4)); 
    } else {
        throw new IllegalArgumentException("Invalid format " + period);
    }
}

However, this parsing is quite lenient and would accept 99:99:99.999 and just let the values overflow. This could be a drawback or a feature.

心凉怎暖 2025-01-02 04:01:29

使用 JODA

PeriodFormatter periodFormat = new PeriodFormatterBuilder()
  .minimumParsedDigits(2)
  .appendHour() // 2 digits minimum
  .appendSeparator(":")
  .minimumParsedDigits(2)
  .appendMinute() // 2 digits minimum
  .appendSeparator(":")
  .minimumParsedDigits(2)
  .appendSecond()
  .appendSeparator(".")
  .appendMillis3Digit()
  .toFormatter();
Period result = Period.parse(string, periodFormat);
return result.toStandardDuration().getMillis();

Using JODA:

PeriodFormatter periodFormat = new PeriodFormatterBuilder()
  .minimumParsedDigits(2)
  .appendHour() // 2 digits minimum
  .appendSeparator(":")
  .minimumParsedDigits(2)
  .appendMinute() // 2 digits minimum
  .appendSeparator(":")
  .minimumParsedDigits(2)
  .appendSecond()
  .appendSeparator(".")
  .appendMillis3Digit()
  .toFormatter();
Period result = Period.parse(string, periodFormat);
return result.toStandardDuration().getMillis();
何以笙箫默 2025-01-02 04:01:29

如果您想使用 SimpleDateFormat,您可以这样写:

private final SimpleDateFormat sdf =
    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    { sdf.setTimeZone(TimeZone.getTimeZone("GMT")); }

private long parseTimeToMillis(final String time) throws ParseException
    { return sdf.parse("1970-01-01 " + time).getTime(); }

但是自定义方法会更有效。 SimpleDateFormat 由于其所有日历支持、时区支持、夏令时支持等,速度相当慢。如果您确实需要其中一些功能,那么缓慢是值得的,但既然您不需要,则可能不需要。 (这取决于您调用此方法的频率,以及您的应用程序是否需要考虑效率。)

此外,SimpleDateFormat 是非线程安全的,这有时会很痛苦。 (在不了解您的应用程序的情况下,我无法猜测这是否重要。)

就我个人而言,我可能会编写一个自定义方法。

If you want to use SimpleDateFormat, you could write:

private final SimpleDateFormat sdf =
    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    { sdf.setTimeZone(TimeZone.getTimeZone("GMT")); }

private long parseTimeToMillis(final String time) throws ParseException
    { return sdf.parse("1970-01-01 " + time).getTime(); }

But a custom method would be much more efficient. SimpleDateFormat, because of all its calendar support, time-zone support, daylight-savings-time support, and so on, is pretty slow. The slowness is worth it if you actually need some of those features, but since you don't, it might not be. (It depends how often you're calling this method, and whether efficiency is a concern for your application.)

Also, SimpleDateFormat is non-thread-safe, which is sometimes a pain. (Without knowing anything about your application, I can't guess whether that matters.)

Personally, I'd probably write a custom method.

简单气质女生网名 2025-01-02 04:01:29

我提供两个选项:

  1. Time4J,一个高级外部日期、时间和时间间隔库。
  2. java.time,内置的现代 Java 日期和时间 API。

SimpleDateFormatDate 是错误的类,因为 1 分钟 30.5 秒的持续时间不是日期,而且这些类早已不再合理使用。

Time4J

这是一个优雅的解决方案。我们首先声明一个格式化程序:

private static final Duration.Formatter<ClockUnit> DURATION_FORMAT 
        = Duration.formatter(ClockUnit.class, "hh:mm:ss.fff");

然后解析并转换为毫秒,如下所示:

    String startAfter = "00:01:30.555";
    
    Duration<ClockUnit> dur = DURATION_FORMAT.parse(startAfter);
    long milliseconds = dur.with(ClockUnit.MILLIS.only())
            .getPartialAmount(ClockUnit.MILLIS);
    
    System.out.format("%d milliseconds%n", milliseconds);

输出为:

90555 毫秒

java.time

java.time.Duration 类只能解析 ISO 8601 格式。所以我首先将您的字符串转换为该格式。它就像 PT00H01M30.555S (不需要前导零,但我为什么要费心删除它们?)

    String startAfter = "00:01:30.555";
    
    String iso = startAfter.replaceFirst(
            "^(\\d{2}):(\\d{2}):(\\d{2}\\.\\d{3})$", "PT$1H$2M$3S");
    Duration dur = Duration.parse(iso);
    long milliseconds = dur.toMillis();
    
    System.out.format("%d milliseconds%n", milliseconds);

输出与以前相同:

90555 毫秒

与 Time4J 的另一个区别是 Java Duration 可以直接转换为毫秒,而无需先转换为只有毫秒的 Duration

链接

I am presenting two options:

  1. Time4J, an advanced external date, time and time interval library.
  2. java.time, the built-in modern Java date and time API.

SimpleDateFormat and Date are the wrong classes to use, both because a duration of 1 minute 30.5 seoncds is not a date and because those classes have long gone out of any reasonable use.

Time4J

This is the elegant solution. We first declare a formatter:

private static final Duration.Formatter<ClockUnit> DURATION_FORMAT 
        = Duration.formatter(ClockUnit.class, "hh:mm:ss.fff");

Then parse and convert to milliseconds like this:

    String startAfter = "00:01:30.555";
    
    Duration<ClockUnit> dur = DURATION_FORMAT.parse(startAfter);
    long milliseconds = dur.with(ClockUnit.MILLIS.only())
            .getPartialAmount(ClockUnit.MILLIS);
    
    System.out.format("%d milliseconds%n", milliseconds);

Output is:

90555 milliseconds

java.time

The java.time.Duration class can only parse ISO 8601 format. So I am first converting your string to that format. It goes like PT00H01M30.555S (the leading zeroes are not required, but why should I bother removing them?)

    String startAfter = "00:01:30.555";
    
    String iso = startAfter.replaceFirst(
            "^(\\d{2}):(\\d{2}):(\\d{2}\\.\\d{3})
quot;, "PT$1H$2M$3S");
    Duration dur = Duration.parse(iso);
    long milliseconds = dur.toMillis();
    
    System.out.format("%d milliseconds%n", milliseconds);

Output is the same as before:

90555 milliseconds

Another difference from Time4J is that the Java Duration can be directly converted to milliseconds without being converted to a Duration of only milliseconds first.

Links

七禾 2025-01-02 04:01:29

对于 .NET / C# 如果 timeString = "00:00:00:014"
假设我们有一个 GetNumeric() 函数来优雅地将 String 处理为 Int。

public static int GetTimeSpanInMs(string timeString)
{
    int returnValue = 0;
    try
    {
        var parts = timeString.Split(":");
        returnValue = GetNumeric(parts[0]) * 1000 * 60 * 60 + GetNumeric(parts[1]) * 1000 * 60 + GetNumeric(parts[2]) * 1000 + GetNumeric(parts[3]);
    }
    catch 
    {
        //handle
    }

    return returnValue;
}

For .NET / C# if timeString = "00:00:00:014"
Assume we have a GetNumeric() function to handle the String to Int gracefully.

public static int GetTimeSpanInMs(string timeString)
{
    int returnValue = 0;
    try
    {
        var parts = timeString.Split(":");
        returnValue = GetNumeric(parts[0]) * 1000 * 60 * 60 + GetNumeric(parts[1]) * 1000 * 60 + GetNumeric(parts[2]) * 1000 + GetNumeric(parts[3]);
    }
    catch 
    {
        //handle
    }

    return returnValue;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文