try {} catch ()

Java, Agile, the Web and other nice things

Feb

3

GWT and JavaScript Date hell

By Olivier Gérardin

You’d think that in 2010, date processing is something that is easily done in Java (and hence GWT), in a consistent cross-platform way. And you’d be wrong.

When I’m talking date processing, I mean simple calendar date (not time) operations, like: get today’s date, add a number of days, compute the number of days between two dates, etc. The original sin, so to speak, is that Java doesn’t have a class to represent a day; Java’s Date class is actually more like a timestamp: it encapsulates a moment in time (with a millisecond precision) stored as the number of milliseconds to/from the moment called “epoch”, which is arbitrarily fixed at January 1, 1970, 00:00:00 GMT.

The methods related to date components (day of month, month, year, etc.) have all been deprecated since the apparition of the Calendar class (JDK 1.1). The trouble is, Calendar isn’t available in GWT’s JRE emulation library. So what do most programmers do? They use the deprecated methods of class Date. For example to create a Date that corresponds to a given day, they would use new Date(y, m, d). Well it’s deprecated, but it works, right?

Wrong. When instantiating a Date object using these deprecated methods, each JavaScript implementation tries to do its best to guess the correct timestamp, based on things such as the current time zone and whether Daylight Savings Time was effective at that time, and of course these rules vary by OS, JavaScript implementation and depend on the client’s regional settings. I’m not going into details now, but the bottom line is: you can’t expect to get a consistent behaviour.

Actually, if you might not notice this problem if all you do is manipulate local dates that were created on the client-side; the problem really becomes a nightmare when you mix locally instanciated dates with serialized dates from the server.

We’ve spent an incredible amount of energy and time to work around this issue, which is made worse by GXT’s DateWrapper and DateTextField. The awkward but kind-of working solution that we use now is to subtract Date.getTimezoneOffset() from Date.getTime() in order to “cancel out” the client’s time zone and DST. Not pretty.

If I had to do my current project again, I would definitely stay away from the Date type on the client side. As primitive as it may sound, if I have to manipulate dates without a time part, I would stick to using a (day, month, year) triplet and do as little date calculations on the client-side as possible.

You’ve been warned!

21 Responses so far

Thanks for the warning. Everyone concerned may want to join/login and “favorite” this issue by clicking on the star: http://code.google.com/p/google-web-toolkit/issues/detail?id=603

Agree with you. I’ve had the same problems you mention above and it is hell. They expect you to use a deprecated java.util.Date with minimal utilitary methods to manipulate heavy date operations.

Currently, I am working on a project where I need to perform the same date-related operations both in browser tier and business tier and the only solution until now has been to use this class. As you know, DateWrapper can only be used on the browser layer since it makes calls to javascript.

Fortunately, this logic is highly isolated and we are expecting GWT creators and contributors to delivery a decent Calendar emulation.

Did you look at Joda-Time (http://joda-time.sourceforge.net/) ?

It has been mentioned as a possible replacement of Java Date, I think it has been suggested actually for GAE as the new primary Date class.

I just found out the Datanucleus now supports Joda-Time (datanucleus is used by the GAE datastore to access BigTable). Maybe it would make sense to for GWT and GAE to support Joda-Time as primary Data class ?

As we were hitting this Date nightmare, I came across Joda-time, which sounded like just what I was looking for… but the GWT port Goda-time http://code.google.com/p/goda-time looks stalled with a warning from 2008 on the front page “The release file has been deprecated until recently identified licensing issues are resolved”…

We have the same need of doing similar date calculations both in the browser and on the business tier, and so we have 2 DateUtils classes with essentially the same methods: one for the browser that uses deprecated Date methods and other homebrew approximations, the other for the server that uses proper Calendar methods. Not pretty.

Only problem I’ve had so far with dates is passing just a date (without the time). GXT will default it to midnight, as will JDBC after you pull it out of the database. So if the client and server are not in the same timezone, there could be some date rolling forward or backward. I solved this by subclassing Date and having a custom encoder (currently through Errai, but it’s also possible in regular GWT). I just do it so that it’s encoded as a yyyy-MM-dd String and decode that on the client or server which makes it midnight in whichever timezone they’re in, thus making it not rollover when it’s passed.

That’s exactly why I recommend against using the Date type if you are just dealing with real dates (days) not timestamps. The whole Java Date/Calendar stuff is a mess, there should be a redesign like the collections package did to replace Vector & co. But i’m afraid Date has too mush legacy for this to happen :(

These date problems are why we interated the excellent datejs library (http://www.datejs.com/) to my latest GWT project. We added a few JSNI utility methods and now we have good date handling on every browser and in every locale. It’s made our lives much easier.

I didn’t know about this library, but it looks exactly like what we needed. Is your GWT wrapper open source or otherwise available?

[…] Running Out; Where is IPv6? Mary-Lynn Manns on Fearless Change Comparing Velocity Across Teams GWT and JavaScript Date hell Maven: The Complete […]

Hi, I stumbled across this article because I was having the exact same problem.. the fact that GWT doesn’t have a proper solution for this is ridiculous, but I did try the datejs library and as far as I can tell it does work very well!
As Zack said, just include the js file in your application and then use it via native JavaScript (JSNI) methods.
Glad I found this post!

Just stumbled upon to a GWT project, which has a DateJs wrapper.

http://code.google.com/p/kiyaa/

Going to use it, or atleast try it in our project.

DateJs looks nice, but I’m not sure it solves the same problem.
Let me know how it goes!

[…] Interface (JSNI) GwtExt DateUtil source code w3schools – JavaScript Date SmartGwt Forum blog.gerardin.info – GWT and Javascript Date Hell Escrito por cirovladimir Archivado en programacion Etiquetado: actual, arithmetic, […]

Take a look at http://code.google.com/p/gwt-calendar-class/ . I’ve started porting java.util.Calendar, java.util.TimeZone, and java.util.Locale to GWT. It’s not a full implementation but it handles most of the basic use cases of Calendar.

This is great! I haven’t tested it extensively but it looks good so far… I hope you don’t mind that I tweeted about it :)

Yeah, that’d be awesome. If you have any feedback feel free to contact me, my email address is on the project page.

Hi Olivier,
I was wondering what was the operation you’ve made in order to sync Date instances generated in the client browser (in ant timezone) and the Dates on the server. Subtracting the Date.getTimezoneOffset by the Date.getTime can make things really messy (at least if you’re using GXTs DateField).

Also, for presenting the Dates coming from the server I’m currently using the DateTimeFormat with a specific TimeZone created in the client side. Looks ok so far. Is that you’re approach as well?

cheers!

[…] muito bem disse o autor do post “GWT and Javascript Date Hell“,  Olivier Gerárdin,  ”You’d think that in 2010, date processing is something that […]

Hi, actually subtracting Date.getTimezoneOffset() was the only reliable cross-platform way that we found. The trick is to set the server timezone to GMT with the appropriate java command line option that I don’t remember right now… For presenting the dates on the client we also use the same approach as you.

[…] cálculo de fechas en GWT tiene sus complicaciones. SmartGwt tiene varias clases y controles para que el usuario seleccione una fecha […]

Leave a comment