Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GWT Date Handing... have client respect server's timezone

Tags:

date

timezone

gwt

I've read many a post here re: GWT date handling.

One in particular that struck a cord with me was this one

Sending a date and timezone from GAE server to GWT client

Anyhow, there's a need on a project I'm working on to be able to display days, hours, minute intervals as labels in a grid. My team has adopted an approach where all date/time instances are passed the client from the server in ISO8601 String format. The server time zone is to be respected by the client. The biz use case is that all date/time instances are in "market time", so that any browser that visits the app will see and work with dates in the "market time" timezone which happens to be GMT-05:00 (if Daylight Savings in effect) or GMT-06:00 (if Standard Time in effect).

I have posted some source on Github, here:

https://github.com/fastnsilver/gwt-datehandling-example

Particularly...

https://github.com/fastnsilver/gwt-datehandling-example/blob/master/src/main/java/me/fns/gwt/datehandling/client/util/CSTimeUtil.java

and the GWTTestCase

https://github.com/fastnsilver/gwt-datehandling-example/blob/master/src/test/java/me/fns/gwt/datehandling/client/util/CSTimeUtilTestGwt.java

in the hopes that someone can stare at the utility (and test) we're employing for date handling and help us see what we're not seeing.

EDIT The basic problem is that CSTimeUtil#hoursInDay(Date) is not being calculated correctly in Production mode for "transition days" This method is used by other methods (like CSTimeUtil#dateToHour(Date) and CSTimeUtil#labelsForDay(Date)).

I have deployed our application with the current implementation of CSTimeUtil and it appears to work, but not quite. I'm really confused by alternate test results when e.g., mvn gwt:test is run in GWT Mode or Production Mode on Windows where the OS timezone is set to various timezones other than U.S. GMT-05:00 or GMT-06:00.

like image 758
Chris Phillipson Avatar asked Feb 18 '23 15:02

Chris Phillipson


2 Answers

Based on some hints from Andrei and some serious blood, sweat and tears, I figured this out on my own. I have updated the code in Github, so if you're curious please go have a look there.

The basics:

  • Make sure all Strings are ISO8601 (no millis) compliant when sent from server to client and vice versa
  • Use DateTimeFormat.getFormat("yyyy-MM-ddTHH:mm:ss.SZZZZ") to format and parse dates
  • Retreive GMT-prefixed time zone info from java.util.Date in "Market time" using DateTimeFormat(Date, TimeZone), where TimeZone param is set as TimeZone.createTimeZone(TZ_CONSTANTS_INSTANCE.americaChicago()) and time zone String retrieved by TimeZone.getISOTimeZoneString(Date)
  • Generating days, see generateDay(Date, int) or hours generateHour(Date, int), from a source date had to take into consideration that an increment or decrement coudl trigger a change in time zone offset if occurring on a "transition day".
like image 142
Chris Phillipson Avatar answered Feb 27 '23 14:02

Chris Phillipson


If you time zone is fixed, why would you use a string to represent date/time? You can send a standard Java Date object to the client. If you want, you can even store all dates and times as Longs and pass Longs only. You also send the GWT's TimeZone Json string for your time zone (once per session). You can find it in the GWT - there is a file with strings for all time zones.

On a client you use DateTimeFormat with many predefined formats to display whatever you need: full date, month and date, date and time, etc. Just remember to create TimeZone object from this Json string and use it in DateTimeFormat.getFormat(...).format(Date, TimeZone).

With this approach you don't have to worry about DST changes (they are encoded in that Json string) and locales. You only pass simple Date or Long objects.

like image 26
Andrei Volgin Avatar answered Feb 27 '23 14:02

Andrei Volgin