簡體   English   中英

如何將 HH:mm:ss.SSS 轉換為毫秒?

[英]How to convert HH:mm:ss.SSS to milliseconds?

我有一個 String 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());

您可以使用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());        
    }
}

如果您想自己解析格式,可以使用正則表達式輕松完成

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,只是讓值溢出。 這可能是一個缺點或特征。

如果你想使用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是非線程安全的,有時是一種痛苦。 (不知道你的申請是什么,我無法猜測是否重要。)

就個人而言,我可能會寫一個自定義方法。

使用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();

我提出了兩個選項:

  1. Time4J,一個高級的外部日期、時間和時間間隔庫。
  2. java.time,內置的現代 Java 日期和時間 API。

SimpleDateFormatDate是使用錯誤的類,因為 1 分鍾 30.5 秒的持續時間不是日期,而且因為這些類早就沒有任何合理的用途了。

時間4J

這是優雅的解決方案。 我們首先聲明一個格式化程序:

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.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

鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM