views:

750

answers:

3

Hi.

I need to force any time related operations to GMT/UTC, regardless the timezone set on the machine. Any convenient way to so in code?

To clarify, I'm using the DB server time for all operations, but it comes out formatted according to local timezone.

Thanks!

A: 

Setting user.timezone property to UTC seems to do the trick.

Can anyone comment on this?

SyBer
This is the correct way to set the default timezone for the entire JVM instance. I had to do this when we had Java environments running in different time-zones physically and passing Date() and Calendar() between systems.
Kevin Brock
+1  A: 

I would retrieve the time from the DB in a raw form (long timestamp or java's Date), and then use SimpleDateFormat to format it, or Calendar to manipulate it. In both cases you should set the timezone of the objects before using it.

See SimpleDateFormat.setTimeZone(..) and Calendar.setTimeZone(..) for details

Eyal Schneider
+2  A: 

The OP answered this question to change the default timezone for a single instance of a running JVM, set the user.timezone system property:

java -Duser.timezone=GMT ... <main-class>

If you need to set specific time zones when retrieving Date/Time/Timestamp objects from a database ResultSet, use the second form of the getXXX methods that takes a Calendar object:

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
ResultSet rs = ...;
while (rs.next()) {
    Date dateValue = rs.getDate("DateColumn", tzCal);
    // Other fields and calculations
}

Or, setting the date in a PreparedStatement:

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
PreparedStatement ps = conn.createPreparedStatement("update ...");
ps.setDate("DateColumn", dateValue, tzCal);
// Other assignments
ps.executeUpdate();

These will ensure that the value stored in the database is consistent when the database column does not keep timezone information.

The java.util.Date and java.sql.Date classes store the actual time (milliseconds) in UTC. To format these on output to another timezone, use SimpleDateFormat. You can also associate a timezone with the value using a Calendar object:

TimeZone tz = TimeZone.getTimeZone("<local-time-zone>");
//...
Date dateValue = rs.getDate("DateColumn");
Calendar calValue = Calendar.getInstance(tz);
calValue.setTime(dateValue);
Kevin Brock
One thing to note about setting the timezone for the entire JVM is that it affects everything, including such things as logging. Just something to keep in mind if that's the desired effect.
Herminator
Yep, that fine.Just one point to mention, that I actually set the user.timezone directly in code, rather then via the -D parameter.
SyBer
@SyBer: That works but you must ensure that you set this before any method calls the TimeZone.getDefault() method. If not you will have some confusion since the default is cached after the first execution. This also means it could be a problem if you do this inside an API/library (hidden from plain view) - be sure to document heavily what you are doing.
Kevin Brock