68

As most people are painfully aware of by now, the Java API for handling calendar dates (specifically the classes java.util.Date and java.util.Calendar) are a terrible mess.

Off the top of my head:

  • Date is mutable
  • Date represents a timestamp, not a date
  • no easy way to convert between date components (day, month, year...) and Date
  • Calendar is clunky to use, and tries to combine different calendar systems into one class

This post (link dead - archive link) sums it up quite well, and JSR-310 also expains these problems.

Now my question is:

How did these classes make it into the Java SDK? Most of these problems seem fairly obvious (especially Date being mutable) and should have been easy to avoid. So how did it happen? Time pressure? Or are the problems obvious in retrospect only?

I realize this is not strictly a programming question, but I'd find it interesting to understand how API design could go so wrong. After all, mistakes are always a good learning opportunity (and I'm curious).

sleske
  • 81,358
  • 34
  • 189
  • 227
  • 1
    A double negative is always bad form...Date is mutable not Date is not immutable. – mP. Oct 15 '09 at 09:43
  • 2
    Hopefully, the new Date and Time APIs of JSR-310, based on Joda-Time, will ship in Java 7. – Pascal Thivent Oct 15 '09 at 09:48
  • 5
    And DateFormat is not designed to be thread-safe... (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4093418) – Arjan Oct 15 '09 at 09:49
  • 10
    @S.Lott: I don't agree. We don't live in isolation. We aren't born as great software architects that know the right solution with no forethought. We have to learn, and learning from past mistakes is useful. – Mario Ortegón Oct 15 '09 at 10:21
  • Hindsight is a wonderful thing, isn't it. I can excuse Date, even if it is a glorified UnixTimestamp with millisecond accuracy tacked on. I can't excuse Calendar. The new APIs should have fifteen years of experience distilled inside them so they work well for programmers (JodaTime is pretty good). – JeeBee Dec 14 '09 at 15:58
  • 1
    And February is month number 1. – Thilo Dec 17 '10 at 06:25
  • 2
    @Thilo: True, but that's actually the least of its problems. I *might* even excuse that, seeing that programmers are used to counting from 0. But then again, DAY_OF_MONTH and DAY_OF_YEAR *are* one-based... so it's not really excusabe. – sleske Dec 17 '10 at 10:34

3 Answers3

45

Someone put it better than I could ever say it:

  • Class Date represents a specific instant in time, with millisecond precision. The design of this class is a very bad joke - a sobering example of how even good programmers screw up. Most of the methods in Date are now deprecated, replaced by methods in the classes below.
  • Class Calendar is an abstract class for converting between a Date object and a set of integer fields such as year, month, day, and hour.

  • Class GregorianCalendar is the only subclass of Calendar in the JDK. It does the Date-to-fields conversions for the calendar system in common use. Sun licensed this overengineered junk from Taligent - a sobering example of how average programmers screw up.

from Java Programmers FAQ, version from 07.X.1998, by Peter van der Linden - this part was removed from later versions though.

As for mutability, a lot of the early JDK classes suffer from it (Point, Rectangle, Dimension, ...). Misdirected optimizations, I've heard some say.

The idea is that you want to be able to reuse objects (o.getPosition().x += 5) rather than creating copies (o.setPosition(o.getPosition().add(5, 0))) as you have to do with immutables. This may even have been a good idea with the early VMs, while it's most likely isn't with modern VMs.

sleske
  • 81,358
  • 34
  • 189
  • 227
gustafc
  • 28,465
  • 7
  • 73
  • 99
  • 1
    The geometry classes are mutable and some have public fields because lots of intenses are created by Swing and back in the beginning this was a hack to improve performance. – mP. Oct 15 '09 at 09:48
  • 10
    Ha, came here to post just this! Can't edit your post (need more rep) but: "... Date represents a specific instant in time, with millisecond precision. The design of this class is a very bad joke - a sobering example of how even good programmers screw up [...] GregorianCalendar is the only subclass of Calendar in the JDK. [...] Sun licensed this overengineered junk from Taligent - a sobering example of how average programmers screw up. " From Peter van Der Linden's comp.lang.java.programmers "Java Programmer's FAQ", online at e.g. http://www.faqs.org/faqs/computer-lang/java/programmers/faq/ – Cowan Oct 17 '09 at 23:04
  • @Cowan: Are you sure? I could not find the quotation in the FAQ you link to. – sleske Oct 12 '12 at 15:47
  • 6
    @sleske: Interestingly, it seems the FAQ changed at one time to remove the quote. Compare the previous version (which used to live at that link), http://www.cs.colorado.edu/~karl/APlus/javafaq.html (see section 5.8), which has the quote above, to the version I linked to —which also says "Credit to Paul Hill who completely rewrote this section, and to the programmers at IBM who implemented much of the Java Date code, and reviewed this section of the FAQ for accuracy." That sounds suspiciously to me like someone didn't like the characterization. :) – Cowan Oct 24 '12 at 13:22
21

Java's early APIs are nothing more than a product of their time. Immutability only became a popular concept years after that. You say that immutability is "obvious". That might be true now but it wasn't then. Just like dependency injection is now "obvious" but it wasn't 10 years ago.

It was also at one time expensive to create Calendar objects.

They remain that way for backwards compatibility reasons. What is perhaps more unfortunate was that once the mistake was realized the old class wasn't deprecated and new date/time classes were created for all APIs going forward. This has to some degree occurred with the JDK 8 adoption of a JodaTime like API (java.time, JSR 310) but really it's too little too late.

sleske
  • 81,358
  • 34
  • 189
  • 227
cletus
  • 616,129
  • 168
  • 910
  • 942
  • 1
    Date predates Calendar by several releases. Date was there from the beginning, and can't be removed easily. Calendar was added because Date is incomplete. – S.Lott Oct 15 '09 at 10:13
  • I remember very well that immutability of String was a novelty and received as much criticism as praise. – BOC May 30 '18 at 14:37
9

Time is itself not easy to measure and to handle with. Just look at the length of the wikipedia article about time. And then, there are different understandings about time itself: a absoulte time point (as a constant), a time point at a certain place, a time range, the resolution of time....

I remember, when i saw java.util.Date the first time (JDK 1.0?) i was really happy about it. The languages i knew of didn't had such a feature. I didn't have think about time conversion etc.

I think it's mess, because everything that changes leaves a mess if you evolve from one level of understanding (XMLGregorianCaldender vs. Date) and requirements (Nanoseconds, past 2030) to higher level, but keeping the old untouched. And java.util.Date is not a Exception. Just look at the I/O subsystem or the transition from AWT to Swing...

And because of that, "we should sometimes press the reset button." (who said that, btw.?)

dz.
  • 1,286
  • 12
  • 12