SimpleDateFormat adding 7 hours?

I'm trying to do a simple subtraction of dates and getting odd results. For some reason when I format it with SimpleDateFormat, there are 7 extra hours difference.

package timedemo;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Timedemo {

    public static void main(String[] args) {
        Date start = new Date(); // time right now
        Date stop = new Date();

        long startTime = start.getTime()-1000; // introduce a second of skew
        long stopTime = stop.getTime();

        SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");

        // First one shows up prior to 1970 epoch. Okay, except for 5 hour variance.
        // Probably a timezone thing, as I'm in EST (-5).
        System.out.println("New date is "+new Date(stopTime - startTime)); 
        System.out.println("Raw Start is "+startTime); // fine
        System.out.println("Raw Stop is  "+stopTime); // fine
        System.out.println("Raw Difference is "+(stopTime-startTime));
        System.out.println("Formatted Start is "+sdf.format(startTime));
        System.out.println("Formatted Stop is  "+sdf.format(stopTime));
        System.out.println("Formatted Difference is "+sdf.format(stopTime-startTime));

    }

}

And the results are:

New date is Wed Dec 31 19:00:01 EST 1969
Raw Start is 1418397344360
Raw Stop is  1418397345360
Raw Difference is 1000
Formatted Start is 10:15:44
Formatted Stop is  10:15:45
Formatted Difference is 07:00:01
  • I had thought it was a timezone thing, but I'm in EST (-5), not MST (-7).
  • I would suspect Daylight Savings, but it's 7 hours, not 1.
  • 12/24 hour difference? 12-7=5 which is my timezone offset... not sure what to make of it though.
  • Kind of out of ideas at this point.

Why the seven hour shift on the last line?

Jon Skeet
people
quotationmark

The "12-7 = 5" is definitely related to the problem... or more accurately, it's "12-5=7", i.e. 5 hours before midnight is 7pm. You'll see that if you format it as a full date/time:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Heck, you can see that in your first line: "Wed Dec 31 19:00:01 EST 1969" - that 19:00 is 7pm, which you're formatting using hh as 07.

Fundamentally, the problem is that you're trying to treat a difference in time as if it's a point in time. I would very strongly urge you not to do that. If you absolutely want to do that (and the difference will always be non-negative but less than 24 hours), then you should set the time zone on SimpleDateFormat to UTC, and use HH instead of hh. But it would be better to use Joda Time or java.time from Java 8 which can represent a Duration, i.e. the difference between two points in time. Date is simply not an appropriate data type for that.

people

See more on this question at Stackoverflow