Question

The users of my application are global, but most don't have user profiles where to save their preferred TimeZone information, so I'd like to make a best-effort guess instead, based on their language setting.

For example, if using the language selection buttons they have selected en_US, then I would render dates in New York TZ, if en_GB then in London TZ, if de_DE, then in Berlin TZ and so forth.

I'm using the Stripes Framework with code like...

<stripes:format value="${someDateValue}" formatType="datetime" formatPattern="medium"/>

...in a lot of places, and wouldn't want to go through all of them to update to something else (custom tag or whatever). I would also rather avoid JavaScript AJAX solutions (mostly because I think they will also cause me to update a lot of stripes:format tags).

Stripes Framework will use default DateFormat for the request Locale, and that is all working (as the date formats change). But all the timezones remain in server TZ (GMT).

So I want some way to set the TimeZone for the default DateFormat-s returned by DateFormat.getDateInstance() and similar before they are returned, but I'm not sure how to do it.

What I tried so far was to set it on the DateFormat instance returned but of course it is returned by-value so it didn't work:

DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("en_US"));
System.out.println(df.getTimeZone().getDisplayName()); // prints Greenwich Mean Time
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println(df.getTimeZone().getDisplayName()); // prints Eastern Standard Time
df = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("en_US"));
System.out.println(df.getTimeZone().getDisplayName()); // prints Greenwich Mean Time again, although if this approach were successful it would print Eastern Standard Time

Any ideas how best to approach this?

My plan B would be a custom Stripes tag, and then changing in the many places where I format dates, but before going that route I'd like to check I'm not missing some simple solution (either a Stripes hook, or a way to change it on more basic Java Locale handling level).

Was it helpful?

Solution 2

Implemented it this way and it appears to work fine:

  • Custom Stripes FormatterFactory which adds a custom DateFormatter
  • DateFormatter gets Timezone offset from the session, having obtained the session from ThreadLocal, and uses it to adjust the DateFormat used to render the Date
  • Interceptor stores the timezone offset from the session into the ThreadLocal
  • JQuery AJAX invocation on page to submit the JavaScript-obtained timezone offset to the backend where it gets stored in the session

OTHER TIPS

User's timezone offset is not carried on HTTP header. Generally there are two approaches:

  1. Create a user profile with time zone setting allowing user to set it
  2. Automatically detect the timezone using javascript's Date object getTimezoneOffset() and post it to the server using ajax. Search the web for example on this.

Or you can do combination of both

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top