Reputation: 5684
I have written a small program that shall print the difference between two Date
objects:
public static void main(final String[] args) throws Exception {
final DateFormat df = new SimpleDateFormat("HH:mm:ss.SSSSSS");
final Date start = Calendar.getInstance().getTime();
Thread.sleep(1000);
final Date end = Calendar.getInstance().getTime();
final long startMilliseconds = start.getTime();
final long endMilliseconds = end.getTime();
final long runtimeMilliseconds = endMilliseconds - startMilliseconds;
final Date runtime = new Date(runtimeMilliseconds);
System.out.print("Start : " + df.format(start));
System.out.println("\t Milliseconds: " + startMilliseconds);
System.out.print("End : " + df.format(end));
System.out.println("\t Milliseconds: " + endMilliseconds);
System.out.print("Runtime: " + df.format(runtime));
System.out.println("\t Milliseconds: " + runtimeMilliseconds);
System.out.println();
System.out.println("Milliseconds from new Date object: " + runtime.getTime());
}
It gives the following output:
Start : 13:24:54.000871 Milliseconds: 1408015494871
End : 13:24:55.000871 Milliseconds: 1408015495871
Runtime: 01:00:01.000000 Milliseconds: 1000
Milliseconds from new Date object: 1000
The difference between the milliseconds is correct, but the newly created Date
object has an extra hour added. The expected output for the runtime
object would be: 00:00:01.000000
. I think this is because of my timezone (GMT+1). How can I compute the difference between two Date
objects and get a new Date
object, that does not include the extra hour, back? I do not want to use Joda-Time or another library.
Upvotes: 1
Views: 69
Reputation: 32949
You issue is that you are treating a time duration as a Date
. 1000 ms does not make any sense as a Date
since Date
is MS since the epoch. Don't try to convert it to a Date
, just use it as a long
.
If you are using Java 8, consider Duration. Or you could use JodaTime. Seems like these might be overkill if you just need the long
.
Per your question, to format it, it depends on if you are using Java 8. If so, use its Duration
. Otherwise, use JodaTime & Duration, Period and PeriodFormatter. This is described in the post:
I will admit this is a more complicated solution than setting the time-zone as others have suggested. However, I suggest it is a more correct solution. This is especially true if the time delta exceeds a day. In that case this solution would be completely wrong.
If the time delta is 24h 1sec, your format of HH:mm:ss.SSSSS
would show 00:00:01.00000
instead of '24:00:01.0000`
Upvotes: 2
Reputation: 97
You are getting this Runtime: 01:00:01.000000 Milliseconds: 1000 beacuse your current time zone is UTC+01:00 . set time zone GMT-00 for the Dateformatter .
Upvotes: 0
Reputation: 2618
To reach your desired behavior you need to set the right time zone, i.e. GMT-00
, because a Date
object created with the constructor you use, will be the milliseconds since January 1, 1970, 00:00:00 GMT.
To do that simply set the DateFormat df
:
df.setTimeZone(TimeZone.getTimeZone("GMT-00"));
immediately after its instantiation (then also Start
and End
dates will be displayed with the new time zone) or before the printing of the new Date runtime
(then Start
and End
dates will be displayed in your local time zone); after that you can reset your original local timezone, if you want to keep it for future use.
The output will be of this kind as you desire:
Start : 11:51:37.000287 Milliseconds: 1408017097287
End : 11:51:38.000287 Milliseconds: 1408017098287
Runtime: 00:00:01.000000 Milliseconds: 1000
Milliseconds from new Date object: 1000
Upvotes: 3
Reputation: 34900
Actually you are using Date
class, and more specifically, SimpleDateFormat
class in wrong way.
You wrote in your question everything right: additional hour in runtime
object is due to your time zone (GMT+1).
The internal representation of your runtime
object is time = 1000
, i.e. it is 00:00:01 of January 1, 1970 GMT
.
If you want to see exactly this date, you should modify your formatter in proper way:
final DateFormat dfGmt0 = new SimpleDateFormat("HH:mm:ss.SSSSSS");
dfGmt0.setTimeZone(TimeZone.getTimeZone("GMT+0"));
Upvotes: 0