stevecross
stevecross

Reputation: 5684

Computing the difference of two dates

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

Answers (4)

John B
John B

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:

joda-time-period-to-string

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

Krishna Kant
Krishna Kant

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

WoDoSc
WoDoSc

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

Andremoniy
Andremoniy

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

Related Questions