2012-01-11 209 views
15

我有一个字符串00:01:30.500,这相当于90500毫秒。我尝试使用SimpleDateFormat,其中包含当前日期的毫秒数。我只需要以毫秒为单位的字符串表示形式。我必须编写自定义方法,它将分割并计算毫秒数?或者还有其他方法可以做到这一点吗?谢谢。如何将HH:mm:ss.SSS转换为毫秒?

我已经试过如下:

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

您使用什么模式创建SimpleDateFormat?你能发布代码吗? – 2012-01-11 20:45:11

回答

31

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

无需预先安装yyyy-MM-dd和1970-01-01。如果将时区设置为GMT,则分析与OP的工作无关。 – 2012-01-11 20:55:59

+0

@JBNizet真实并且很好。我故意包含了额外的日期信息,因为我认为它更好地显示了真正发生的事情。 – 2012-01-11 21:05:06

+0

@AndreasWederbrand:让它在这里工作的“诀窍”是将日期设定为1970年1月1日。但假设如果我今天不给,那么它会起作用吗? – 2013-03-15 04:43:59

2

如果你想使用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是非线程安全的,这有时很痛苦。 (不知道你的应用程序的任何事情,我不能猜测是否重要。)

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

+0

无需预先添加yyyy-MM-dd和1970-01-01。如果将时区设置为GMT,则分析与OP的工作无关。 – 2012-01-11 20:55:28

+0

@JBNizet:在我的系统中,这是真的,但OP写道他/她的方法给出了“包括当前日期在内的毫秒数”,所以我假设他/她的JDK的SimpleDateFormat实现不能调用calendar.clear( )'。我没有看到Javadoc中的任何内容,表明SimpleDateFormat必须默认为1970-01-01。你知道这是否有保证吗? – ruakh 2012-01-11 21:03:08

1

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

如果你想自己解析格式,你可以用正则表达式,如

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并让数值溢出。这可能是一个缺点或功能。

+0

嘿我已经使用你的方法,但它给出了一个加之间的结果字符,这是由于你使用了L与3600000 – Prateek 2013-04-09 10:27:32

+0

可能不是,L是使它很长。哪一部分给出的结果是 - ? dateParseRegExp返回一个没有 - 的长整数(除非它是负数)。它是否具有 - ?的匹配组之一。 – 2013-04-09 11:06:51

+0

OOPS不是因为我的不好。 – Prateek 2013-04-09 12:42:14