I'm experiencing a problem when converting strings to a UTC data, and then to various timezones. It appears that my program behaves differently depending on whether I convert to EST or PST. Here is my code:
SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
utcFormat.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
Date date = utcFormat.parse("2014-08-18 17:00:17");
SimpleDateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
localFormat.setTimeZone(java.util.TimeZone.getTimeZone("PST"));
System.out.println(localFormat.format(date));
If I run the code above, here is my output:
2014-08-18 10:00:17
This reflects a 7 hour offset from the UTC time provided: 2014-08-18 17:00:17. This is what I would have expected. Now if I change that date to 2014-11-18 17:00:17 (changed the month from August to November), here is the output produced:
2014-11-18 09:00:17
This is fine too as far as I can tell. The output reflects an 8 hour offset from UTC, and I believe this is due to the fact that November is not in Daylight Savings time, while August is.
The problem I'm having is that the same code above works differently if I change the time zone from "PST" to "EST". When I change to EST I get the same time output no matter whether my date is in August or November.
Here is the output using EST and 2014-08-18 17:00:17
2014-08-18 12:00:17
Here is the output using EST and 2014-11-18 17:00:17
2014-11-18 12:00:17
In both cases, the output represents a 5 hour offset from UTC which makes sense only during November, not during August.
Can anyone explain to me what I am doing wrong?
@Compass is right. Here is the code you would use:
From the Documentation for TimeZone
Instead of
"EST"
,"US/Eastern"
will be much clearer as to your intent.These are the supported US aliases.
Instead of using
EST
, you should useAmerica/New_York
orUS/Eastern
(these are aliases). The three letter timezone abbreviations are ambiguous and you can't be sure what you're getting.The answer by Dave Morrissey is correct.
Yes. You are using a terrible and confusing date-time library.
Avoid
java.util.Date
The java.util.Date and .Calendar classes are notoriously troublesome, flawed in both design and implementation. Use a decent library. In Java that means either Joda-Time or the new java.time package in Java 8 (inspired by Joda-Time, defined by JSR 310).
Time Zone
While a j.u.Date has no time zone, in both Joda-Time and java.time a date-time object does indeed know its own assigned time zone. Makes this work much easier and more sensible.
Time Zone Names
Use proper time zone names. Avoid the 2, 3, or 4 letter codes as they are neither standardized nor unique. Most of those proper names are
Continent/CityOrRegion
.Daylight Saving Time
You should not worry about Daylight Saving Time. Let the date-time library do the heavy lifting there. All you need to do is be sure your library is using a fresh version of the time zone database. Politicians enjoy redefining DST.
ISO 8601
Both Joda-Time and java.time support ISO 8601 formats as their defaults in parsing and generating string representations of date-time values.
Joda-Time Example
Here is some example code in Joda-Time 2.4. All of the DateTime objects in this example represent the same simultaneous moment in the history of the Universe but adjusted to show the wall-clock time as seen by a person in each locality.
That's because
EST
isET
outside of saving and its shift is constant and it complementary zone for daylight saving period isEDT
.Ergo you should use
ET
to get the expected behavior. More on Wikipedia