Reputation: 765
I am trying to convert the ZonedDateTime to a Date. Looks like in the conversion, it looses the time zone and gets my local time.
System.out.println("zoneDate1::::::::::"+ZonedDateTime.now(ZoneId.of("America/Chicago")));
System.out.println("zoneDate1:Date::::::::::"+Date.from(ZonedDateTime.now(ZoneId.of("America/Chicago")).toInstant()));
The above outputs as below:
zoneDate1::::::::::2016-04-15T17:35:06.357-05:00[America/Chicago]
zoneDate1:Date::::::::::Fri Apr 15 18:35:06 EDT 2016
Is this because this is a Date type? How would i go about doing this kind of conversion and conserve the zoned time?
Upvotes: 1
Views: 1474
Reputation: 2830
If your database allows you to store the timestamp along with the timezone, you should go ahead and save it as a timestamp.
If not, I would recommend that you store the date-time as per your timezone (or GMT). Add an additional column in the table to hold the value of the user's timezone.
When you fetch the value from the database, you can convert it to the user's timezone. Avoid storing just the date.
Upvotes: 0
Reputation: 338564
What is the problem? What did you expect? I see no misbehavior.
Your java.time type (ZonedDateTime
) is assigned a time zone of America/Chicago
.
Your JVM apparently has an assigned time zone related to east coast of North America, the clue being the EDT
value seen in string output. The toString
method on java.util.Date applies your JVM’s current default time zone when generating its textual representation of the date-time value. Poorly designed, this behavior is trying to be helpful but is actually confusing because you cannot actually get or set this time zone on the java.util.Date object.
At any rate, the east coast of North America (such as America/New_York
time zone) is an hour ahead of America/Chicago
. So you are seeing 17:xx:xx
time for Chicago and 18:xx:xx
for Eastern Daylight Saving Time. These values are correct.
You should call java.util.TimeZone.getDefault()
when investigating the behavior of the old date-time classes.
The bigger problem is that you are even using these old date-time classes such as java.util.Date/.Calendar. They are poorly designed, confusing, and troublesome. Avoid these old classes altogether. They have been supplanted in Java 8 and later by the java.time framework.
Also, avoid using 3-4 letter zone abbreviations like EDT
. These are neither standardized nor unique. Use proper time zone names in continent/region format.
Instant
To capture the current date-time in java.time, just use Instant
. This class captures a moment on the timeline in UTC. Do most of your work in UTC. No need for time zones unless expected by your user when displayed in the user interface.
Instant now = Instant.now();
To send to your database, first make sure you have defined the column in the table as something along the line of the SQL standard TIMESTAMP WITH TIME ZONE
. By the way, support for date-time types various among databases with some doing a much better job than others.
Hopefully JDBC drivers will be updated someday to directly handle the java.time types. Until then, we must convert into a java.sql type when transferring data to/from a database. The old java.sql classes have new methods to facilitate these conversions.
java.sql.Timestamp
For a date-time value like Instant
, we need the java.sql.Timestamp
class and its from( Instant )
method.
java.sql.Timestamp ts = java.sql.Timestamp.from( now );
Avoid working in java.sql.Timestamp
as it is part of the old poorly-designed mess that is the early Java date-time classes. Use them only for database transfer, then shift into java.time immediately.
Instant instant = ts.toInstant();
So simple, no time zones or offset-from-UTC involved. The Instant
, java.sql.Timestamp
, and database storage are all in UTC.
ZonedDateTime
When you do need to shift into some locality’s wall-clock time, apply a time zone.
ZoneId zoneId = ZoneId.of( "America/Chicago" ); // Or "America/New_York" and so on.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Upvotes: 2
Reputation: 466
Huh? Date doesn't have time zones so, this is probably why it's failing. Maybe this is what you're looking for:
Date.from(java.time.ZonedDateTime.now().toInstant());
Upvotes: 0