views:

2510

answers:

6

What is the best way to set the time zone in Tomcat for a single web app? I've seen options for changing the command-line parameters or environment variables for Tomcat, but is there a way to set it that is self-contained in the WAR file and not dependent on any Tomcat configuration?

Edit: to reemphasize, I'm looking for a solution that can be contained within a WAR file, not dependent on Tomcat configuration. To put it another way, can one web app be configured to have a different time zone than other apps running in the same Tomcat instance?

+1  A: 

Set the system variable to CATALINA_OPTS=-Duser.timezone=America/Denver

You can also specify the CATALINA_OPTS in the $TOMCAT_HOME/bin/catalina.sh or %TOMCAT_HOME%\bin\catalina.bat file as well.

Here's a list of acceptable timezones.

Source

Cuga
This solution would change the overall time zone for the Tomcat server; the question author wanted to set different time zones per webapp.
gareth_bowles
+4  A: 

EDIT: I was wrong about this. This edit corrects it.

The answer is that you cannot portably set the (default) timezone for a single webapp. But if you are using Java 6 (at least), the java.util.TimeZone class implements the default timezone methods getDefault(), setDefault() and setDefault(TimeZone) using an inheritable thread local. In other words, calling setDefault() only affects the current thread and future child threads.

The behaviour is not documented in the Sun Javadocs. It works for Java 6 and 5 (see above), but there are no guarantees it will work in older or newer Sun JREs. However, I would be very surprised if Sun decided to change/revert to a 'global' model for the default TimeZone. It would break too many existing applications, and besides globals are BAD.

Stephen C
A: 

Check out the SimpleTimeZone. You can create an instance based on a time zone ID and use that to display dates/times using that time zone. If you wanted, you could read that ID from a project specific configuration file.

Tai Squared
+3  A: 

The only way I found is to setup a filter and change the timezone in the filter,

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    TimeZone savedZone = TimeZone.getDefault();
    TimeZone.setDefault(webappZone);
    chain.doFilter(request, response);
    TimeZone.setDefault(savedZone);
}

The setDefault() changes the zone for the thread. So everything running in the thread inside the filter will have a different default timezone. We have to change it back because the thread is shared by other apps. You also need to do the same for your init(), destroy() methods and any other thread you might start in your application.

I had to do this because a third-party library assumes default timezone and we don't have source code. It was a mess because this changes log timezone but we don't want log in different times. The correct way to handle this is to use a specific timezone in any time value exposed to end users.

ZZ Coder
You should use try-finally for that. Note, any threads created during the processing will inherit the timezone that was set at the time. Future JREs may have differently weird behaviour.
Tom Hawtin - tackline
Good catch. I agree this may break with future JREs because I don't see anywhere in the doc saying setDefault() only affects the calling thread. This is a hack after all. Don't do it unless you have to.
ZZ Coder
I hope that you realize that this will fail BIG TIME if you have multiple webapps. Calling setDefault() changes the default timezone for every single thread in the JVM.
Stephen C
We tried this on Java 5 and it only affected the calling thread. All other webapps are not affected. I agree this is an undocumented feature and it may break in future JRE.
ZZ Coder
You are right. TimeZone.get/setDefault(...) use thread locals on OpenJDK as well. It is not documented, but I doubt that Sun would change this.
Stephen C
A: 

The best way is to modify the web application so it accepts explicit time zone configuration through web.xml instead of using the default JVM timezone.

mikaelhg
A: 

@mikaelhg And how do you do that? I've been looking up on Google and I haven't been able to configure the timezone through the web.xml file.

CSA