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.d1
, you get d2
d1
, it should be created as a PST
date, why is it getting created as a PDT date?
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"))
.
See more on this question at Stackoverflow