How to convert HH:mm:ss.SSS to milliseconds?
Solution 1
You can use SimpleDateFormat
to do it. You just have to know 2 things.
- All dates are internally represented in UTC
-
.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());
}
}
Solution 2
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.
Solution 3
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();
Solution 4
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.
Solution 5
I am presenting two options:
- Time4J, an advanced external date, time and time interval library.
- 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})$", "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
- Time4J - Advanced Date, Time, Zone and Interval Library for Java
- Oracle tutorial: Date Time explaining how to use java.time.
Comments
-
Ahamed almost 2 years
I have a String
00:01:30.500
which is equivalent to90500
milliseconds. I tried usingSimpleDateFormat
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());