Format of time is incorrect

First of all, you’re mistaking 2 different concepts:

  1. A time of the day, such as 10 AM or 15:30:45
  2. A duration, which is an amount of time, such as 1 year, 2 months and 10 days or 10 hours, 25 minutes and 30 seconds

Although both might use the same words (such as “hours” and “minutes”), they’re not the same thing. A duration is not attached to a chronology (10 hours and 25 minutes relative to what?), it’s just the amount of time, by itself.

SimpleDateFormat and DateTimeFormatter are designed to format dates and times of the day, but not durations. Although converting a duration to a time and “pretending” it’s a time of the day to format it might work, it’s not the right way.

Unfortunately, there are no built-in formatters for a duration. So you’ll have to format it manually.

Another detail is that you are multiplying 1.4345 by 1000 (resulting in 1434.5), and then casting to a long(so the value is rounded to 1434) – the last digit is lost.

One way to do it is to parse the string to a double and then multiply by 1 billion to get the value as nanoseconds (I don’t know if you’ll work with more than 4 digits, so I’m considering nanosecond precision):

// convert the string value to a total of nanoseconds
int nanosPerSecond = 1_000_000_000;
long nanos = (long) (Double.parseDouble(realTimeStr) * nanosPerSecond);

Now we must format it manually. First I’ve extracted the number of hours, minutes, seconds and nanoseconds from the total nanos value:

long hours = nanos / nanosPerSecond / 3600;
nanos -= hours * 3600 * nanosPerSecond;
long minutes = nanos / nanosPerSecond / 60;
nanos -= minutes * 60 * nanosPerSecond;
long seconds = nanos / nanosPerSecond;
nanos -= seconds * nanosPerSecond;

Then I created an auxiliary method to build the output:

// auxiliary method
public void addValue(long value, StringBuilder sb) {
    if (value < 10) {
        sb.append("0");
    }
    sb.append(value);
}

And used it to join the pieces:

StringBuilder sb = new StringBuilder();
addValue(hours, sb);
sb.append(":");
addValue(minutes, sb);
sb.append(":");
addValue(seconds, sb);
sb.append(".");
addValue(nanos, sb);

// remove the extra zeroes in the end
String output = sb.toString().replaceAll("0*$", "");
System.out.println(output);

The output is:

00:00:01.4345

Leave a Comment