web-dev-qa-db-ja.com

HH:mm:ss.SSSをミリ秒に変換する方法は?

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());
18
Ahamed

SimpleDateFormatを使用して実行できます。あなたは2つのことを知っている必要があります。

  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());        
    }
}
36

自分でフォーマットを解析する場合は、次のような正規表現を使用して簡単に実行できます

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を受け入れ、値がオーバーフローするだけです。これは、欠点または機能の可能性があります。

6
Roger Lindsjö

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はスレッドセーフではないため、時々苦痛になります。 (アプリケーションについて何も知らなくても、それが重要かどうかは推測できません。)

個人的には、おそらくカスタムメソッドを書くでしょう。

2
ruakh

[〜#〜] 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();
2
Louis Wasserman