Reputation: 2658
I am trying to display a time difference into a string which follows the form 00:00:00 (hours:minutes:seconds), zero-padded. I have the following code:
long timeDiff = System.currentTimeMillis() - mStartRecordingTime;
time = DateFormat.format("hh:mm:ss", timeDiff).toString();
I was testing it when the timeDiff was no more than a few seconds but the hour does not show as 00. I am in the JST timezone by the way.
Upvotes: 2
Views: 5570
Reputation: 339472
Duration.between(
LocalTime.of( 12 , 5 , 0 ) ,
LocalTime.of( 12 , 7 , 0 )
).toString()
PT2M
If, against my strong recommendation to use Duration
, you insist on using ambiguous/confusing time-of-day formatting:
LocalTime.MIN.plus(
Duration.between(
LocalTime.of( 12 , 5 , 0 ) ,
LocalTime.of( 12 , 7 , 0 )
)
).toString();
00:02
To force all three components (hours, minutes, seconds), use the predefined DateTimeFormatter.ISO_LOCAL_TIME
.
LocalTime.MIN.plus(
Duration.between(
LocalTime.of( 12 , 5 , 0 ) ,
LocalTime.of( 12 , 7 , 0 )
)
).format( DateTimeFormatter.ISO_LOCAL_TIME )
00:02:00
Do not abuse a date-time class such as java.util.Date
to store elapsed time. Such a class represents a moment, not a span of time.
Do not use troublesome old date-time classes such as java.util.Date
. Those are now supplanted by java.time classes.
Instant
The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Get the current moment.
Instant now = Instant.now();
Simulate a later time.
Instant future = now.plus( Duration.ofMinutes( 5 ) );
Duration
Capture elapsed time with a Duration
or Period
object. Each of these represent a span of time, the first handles days-hours-minutes-seconds and the second handles years-months-days.
Duration duration = Duration.between( now , future );
To present that duration value as a String, do not use time-of-day formatting as that is ambiguous. Instead use standard ISO 8601 format for durations. This format, PnYnMnDTnHnMnS
, marks the beginning with a P
. The T
in the middle separates the years-months-days portion from the hours-minutes-seconds portion. For example, two and a half hours is PT2H30M
. Our example here of five minutes is PT5M
.
String output = duration.toString(); // PT5M
LocalTime
If you do have an actual time-of-day and want to format with padding zeros, use the default format of LocalTime::toString
.
LocalTime.now( ZoneId.of( "America/Montreal" ) ).toString(); // 02:03:04.789Z
Another example. Again, I do not recommend abusing LocalTime
this way. (Instead, stick with Duration
for elapsed time.)
LocalTime start = LocalTime.now( ZoneId.of( "America/Montreal" ) );
LocalTime stop = start.plusMinutes( 7 );
Duration d = Duration.between( start , stop );
LocalTime result = LocalTime.MIN.plus( d ); // I do *not* recommend abusing `LocalTime` this way. Use `Duration` instead for elapsed time.
DateTimeFormatter f = DateTimeFormatter.ISO_LOCAL_TIME ;
String output = result.format( f );
System.out.println( "output: " + output );
output: 00:07:00
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
Upvotes: 0
Reputation: 13133
Where did you get mStartRecordingTime? It doesn't look to me like it was set with System.currentTimeMillis() in the same locale; if it had been, then the time difference would have reflected the actual difference and this would have worked. It appears that the recording time somehow got set with UTC, 9 hours away from JST.
The other poster is correct, a date produced with this value would be near epoch, but if you're just trying to get hours, minutes, and seconds, then you should be all right. Keep in mind that you're dealing with elapsed time, not clock/calendar time, so I wouldn't expect the date formatting (as opposed to time formatting) things to work for you.
Upvotes: 2
Reputation: 10994
You need to compensate for the time zone. With what you have, it is probably easiest to change the date formatter to use UTC as the time zone. Here is some code that should help:
long timeDiff = System.currentTimeMillis() - mStartRecordingTime;
DateFormat df = new SimpleDateFormat("HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String time = df.format(new Date(timeDiff));
Note the change to 'HH' is the date format to display times in a 24 hour format.
Upvotes: 0
Reputation: 117647
Use SimpleDateFormat
:
long timeDiff = System.currentTimeMillis() - mStartRecordingTime;
String time = new SimpleDateFormat("hh:mm:ss").format(new Date(timeDiff));
Upvotes: 2