问题
String realTimeStr = "5.2345";
Double realTimeDbl = Double.parseDouble(realTimeStr);
long realTimeLng = (long) (realTimeDbl*1000);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSSS", Locale.getDefault());
log("Duration: " + sdf.format(new Date(realTimeLng - TimeZone.getDefault().getRawOffset())));
Current output:
Duration: 00:00:05.0234
Desired output:
Duration: 00:00:05.2345
I also tried another method, still no good:
String realTimeStr = "1.4345";
Double realTimeDbl = Double.parseDouble(realTimeStr);
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("HH:mm:ss.SSSS").withZone(ZoneId.of("UTC"));
Instant instant = Instant.ofEpochMilli((long)(realTimeDbl*1000));
String t = formatter.format(instant);
System.out.println("Duration: " + t);
Current output:
Duration: 00:00:01.4340
Desired output:
Duration: 00:00:01.4345
I have googled for some time. Any ideas what is causing this?
回答1:
First of all, you're mistaking 2 different concepts:
- A time of the day, such as
10 AM
or15:30:45
- 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
回答2:
The problem resides in the format, as noticed by Joe C, probably meaning at this line:
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSSS", Locale.getDefault());
try changing it removing one "S"
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault());
notify us if it's correct =)
回答3:
package com.stackoverflow.examples;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class TimeStamp {
public static void main(String[] args) {
String realTimeStr = "5.2345";
Double realTimeDbl = Double.parseDouble(realTimeStr);
long realTimeLng = (long) (realTimeDbl * 1000);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSSs", Locale.getDefault());
System.out.println("Duration: " + sdf.format(new Date(realTimeLng - TimeZone.getDefault().getRawOffset())));
}
}
I tried SSSs
instead of SSSS
来源:https://stackoverflow.com/questions/46083126/format-of-time-is-incorrect