25

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?

Community
  • 1
  • 1
nogridbag
  • 3,521
  • 4
  • 38
  • 51

2 Answers2

7

I've never looked at date4j until now, but I read through the documentation, and I have one concrete problem, and one opinion about what is wrong with it.

First, the concrete problem. It does not maintain Timezone internally. So there is ambiguity about daylight saving. Consider the transition Sunday when 1:59:59am (EDT) becomes 1:00:00am (EST). Clearly, in that day, saying 1:30am is ambiguous. That time happens twice. So the following is ambiguous

new DateTime("2011-11-06 01:30:00")

Second, my opinion. The problem with Date was that it didn't maintain Timezone. By the time Calendar came along, the damage was done. Furthermore, Calendar itself didn't do itself any favors by being mutable. But at the heart, the solution has to include not just moment, but where it was perceived -- timezone, culture, locale sort of stuff. These then need to be maintained alongside the moment when persisted to database, serialized, communicated, whatever. This same personal principle makes me humbly suggest that even xsd:dateTime falls short because it simply allows a date+time to be expressed relative to UTC, it has no provisions to supply whether, for example, daylight saving was being observed.

Dilum Ranatunga
  • 13,254
  • 3
  • 41
  • 52
  • It seems there's ambiguity both ways. For instance, if you're writing a Calendar app like Google Calendar and a user schedules an event at 1:30am, which instant do you store in the database? – nogridbag Aug 25 '11 at 05:56
  • I'm not saying that anyone does perfectly now, just saying that one has no hope of dealing with the problem without keeping additional detail in the DateTime instances. – Dilum Ranatunga Aug 25 '11 at 06:30
  • By the way, I'm not disagreeing with you. I believe your answer is correct but will wait for others to post. If you're doing something simple like logging the specific instant some event happened - a message was posted, an item was deleted then it seems date4j may not work for the reason you stated. – nogridbag Aug 25 '11 at 06:32
  • This new DateTime("2011-11-06 01:30:00") is not ambigous. It is equivalent to new DateTime("2011-11-06 01A:30:00") and the second time when it is again "01:30" is new DateTime("2011-11-06 01B:30:00") however I'm not sure where the A and B is to be put. – Angel O'Sphere Aug 25 '11 at 14:30
  • Oh I see now what your point was. This DateTime does not take leap hours into account according to its documentation: ■it ignores all non-linearities: summer-hours, leap seconds, and the cutover from Julian to Gregorian calendars. This is pretty silly and makes it unuseable exactly in those cases where I want not to use java.util.Date. – Angel O'Sphere Aug 25 '11 at 14:38
  • 1
    Yes, at the heart of the matter -- calendar and time is complicated. There's no getting around it. At the same time we can't expect everyone to be experts on the topics. So APIs need to be prescriptive in nature -- (unintrusively) force users to follow patterns that address issues underneath. Things like leapseconds in particular are uninteresting to most people, even when calculating time intervals. But by not having preference profiles and internally supporting the complexities, either the code or outcome suffers. – Dilum Ranatunga Aug 25 '11 at 16:13
1

It's four years later and I've come across this question. For me, the problem #1 with date4j is bugs. I know you specifically didn't ask about those, but it is a major problem.

More specifically, the bugs themselves aren't a problem on their own, it's the complete absence of some kind of bug reporting system that bothers me about date4j. There's not even a mailing list, as far as I know, there isn't anything at all. I know this probably isn't very interesting for a discussion about what date/time API should be like, but still, infrastructure is important.

Lacking one may very well be a reason why a library is not adopted widely.

kralyk
  • 4,249
  • 1
  • 32
  • 34
  • Four years later and we can finally start using the new Java 8 Date and Time API... :) Perhaps in another 4 years I will be able to use the new classes natively in my Grails project without rolling my own usertype mapping or using a third party mapping lib... – nogridbag Jul 01 '15 at 17:30
  • 1
    For info, Date4J is now on GitHub, where issues can be reported. https://github.com/johanley/date4j – Chris Knight Jan 08 '16 at 23:08