When you ask for the explanation of your problem I will be honest with you: You are misusing SimpleDateFormat
for formatting a duration. It was never meant for this use and is not designed to give you the expected result if you try it anyway. The problem you got is not the only problem you will have. If your duration grows to more than 24 hours, the whole days will not be formatted, so your result will be wrong in a different way.
Apart from that, these days I recommend not using the SimpleDateFormat
class at all. Its replacement is java.time.format.DateTimeFormatter
, it came out in 2014 and comes with quite fewer negative surprises. It is not a good choice for formatting a duration either, though.
So what is a good choice? I will give you the Java 9 answer first because it is easy:
Duration dur = Duration.ofMillis(5007);
String hmss = String.format("%02d:%02d:%02d:%03d",
dur.toHours(),
dur.toMinutesPart(),
dur.toSecondsPart(),
dur.toMillisPart());
The main advantage isn’t even the ease, it’s the clarity. For example, with this code no one needs to ask the question I asked in a comment, is it a point it time or a duration? The code very clearly states that it is a duration.
For Java 6, 7 and 8, you may still use the Duration
class (in Java 6 and 7 through the ThreeTen Backport), but it doesn’t lend itself that easily to formatting, so I think I would resort to using the TimeUnit
enum as in the question I had linked to (the link you asked me to remove again):
long millis = 5007;
long hours = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
millis -= TimeUnit.SECONDS.toMillis(seconds);
String hmss = String.format("%02d:%02d:%02d:%03d", hours, minutes, seconds, millis);
The result is the desired
00:00:05:007
To illustrate the point I was trying to make about what happens when the duration is more than 24 hours, let’s try to give it 100 000 000 milliseconds (there are 86 400 000 millis in a day):
27:46:40:000