Как преобразовать HH: mm: ss.SSS в миллисекунды? - PullRequest
17 голосов
/ 12 января 2012

У меня есть строка 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());

Ответы [ 4 ]

36 голосов
/ 12 января 2012

Вы можете использовать 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());        
    }
}
6 голосов
/ 12 января 2012

Если вы хотите проанализировать формат самостоятельно, вы можете легко сделать это с помощью регулярного выражения, такого как

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 и просто позволит значениямпереполнение.Это может быть недостаток или особенность.

2 голосов
/ 12 января 2012

Использование 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 голосов
/ 12 января 2012

Если вы хотите использовать 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 не является потокобезопасным, что иногда является болью. (Не зная ничего о вашем приложении, я не могу догадаться, имеет ли это значение.)

Лично я бы, наверное, написал собственный метод.

...