I recently came across date4j, an extremely simple library (essentially a single class) for working with dates in Java. Conceptually, I really like the "idea" of date4j. In fact, after reading both the entire main site and the documentation in the javadoc, I pretty much agree with everything stated.
Now, there may be several reasons why I shouldn't use date4j - bugs, performance, lack of users, etc. I'm not asking about those things. I'm asking, conceptually, what's wrong with the idea of date4j (for the majority of the applications out there)? Surely, there may be some applications which need something like joda or threeten - but I believe those to be in the minority.
The normal advice people give to users dealing with dates/times (pretty much everyone writing an java app) is something along the lines of:
- Use joda-time instead of java.util.Calendar
- Set your web server to UTC
- Set your database server to UTC
- Store your date-time's in UTC
In fact, the last three bullet points illustrate the problems with the current mental model people have when working with dates. People try to manage timezones at both the application and database level (not to mention ORM frameworks add another layer of abstraction which complicates things further).
You should not have to do those things. If you're using java.util.Calendar, for instance, and you are manipulating a time in some user defined timezone:
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
c.set(Calendar.YEAR, 2011);
c.set(Calendar.MONTH, 0);
c.set(Calendar.DAY_OF_MONTH, 1);
c.set(Calendar.HOUR_OF_DAY, 3);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
This represents an "instant" in time regardless of timezone. You should be able to persist this time to and from the database without worrying about any sort of "conversions" happening. It shouldn't matter if the database is in Shanghai timezone and the webserver is in Los Angeles time zone - the instant in time is the same regardless.
One problem is some databases attempt to manage timezones for you (I'm looking at you, Postgres! grr!) and to make it worse the behavior at the JDBC driver level is vendor specific - i.e. PreparedStatement.setDate/getDate.
The mental model that date4j uses seems to get rid of all the confusion. For example, explicitly forcing uses to provide a timezone when calling now(). There's some very good recommendations on the site for using the library (these things I was already doing in my own app previously) such as:
- don't use a database type which attempts to manage timezones
- store timezone as a separate column (if required)
Why aren't more people adopting a library like date4j?