Java Creating a date in PST returns a date in PDT

public class TestTimeZone {

  public static void main(String[] args) throws ParseException {
    System.setProperty("user.timezone", "PST");
    TimeZone.setDefault(null);
    Date d1 = new Date(1257062400000L);
    Date d2 = new Date(d1.getTime() + 3600000);
    DateFormat f = new SimpleDateFormat("yyyy-MM-dd-HH");
    System.out.println(f.format(d1).equals(f.format(d2)));  // true
    System.out.println(d1.equals(f.parse(f.format(d1))));   // false
    System.out.println(d1);                                 // Sun Nov 01 01:00:00 PDT 2009
    System.out.println(d2);                                 // Sun Nov 01 01:00:00 PST 2009
  }
}
  • d1 and d2 are clearly different, so their formats shouldn't be same.
  • when you format and parse d1, you get d2
  • I set time zone to PST and then create d1, it should be created as a PST date, why is it getting created as a PDT date?
Jon Skeet
people
quotationmark

d1 and d2 are clearly different, so their formats shouldn't be same

Well they wouldn't be if you had an unambiguous format - but you don't. (Heck, even leaving time zones aside you're only formatting to the hour, so it's trivial to create non-equal Date values that format to the same string.)

You're formatting the local time in the system default time zone, which means that if the time zone's UTC offset goes back (as it does in America/Los_Angeles on November 1st 2015, for example) you can have the same local time occurring twice... so you get the same string output for two different times. When you call parse, how are you expecting the formatter to infer information as to which of the original values you meant?

Note that there's no such thing as a java.util.Date in a particular time zone - a Date just represents a number of milliseconds since the Unix epoch.

Also note that PST isn't really a time zone identifier - you'd be better off using the IANA identifiers such as America/Los_Angeles. If you really want a time zone of UTC-8 with no DST changes, you can use Etc/GMT+8 instead. The +8 (instead of -8) is due to the use of Posix-style offsets here. Somewhat confusing... Another alternative would be to call TimeZone.setDefault(new SimpleTimeZone(-28800000, "UTC-8")).

people

See more on this question at Stackoverflow