Designing a Date/Calendar alternative

This is likely not the first time you’ve heard that Date and Calendar classes in the JDK just don’t cut it and you likely have fought with one or both on more than one occasion.

The main problems with Date are:

  • it exposes nothing to do date manipulation or math
  • it doesn’t provide sufficient control over timezone
  • it isn’t immutable so passing around Dates can be dangerous

The Calendar class was intended to break out that point in time and provide access to its individual pieces (hour, seconds, day of month, etc.). In doing so, the ability to mutate the calendar’s fields individually or even perform date math became possible.

Unfortunately, Calendar has these pretty major flaws:

  • it is mutable, which makes passing around instances dangerous
  • thread-safety becomes an issue because of its mutability
  • mutation methods are complicated and have caveats

Alternatives

It makes sense to use an alternative to these in everyday use for these basic cases and once you have the alternative, it becomes the ideal choice for any date use. I won’t comment on Joda much which is being considered as a basis for introducing these types of improvements into Java 7 as when we undertook creating these improved representations here at Carfey Software, no feasible alternative existed. Regardless, what we ended up with is much leaner, cleaner and more targeted then what Joda has become. What I’ll do instead is go over the design decisions and requirements for an alternative, some of which you may recognize from Joda.

First, there are many times that we’d like to be able deal with a Date with no time component and Time without the date component. So we want 3 primary classes, Date, Time and DateTime. Secondly, since we’re going to support manipulations, the classes all need to be immutable. Those two key approaches already solve many pains we experience when dealing directly with the JDK classes.

Let’s also create our own DateFormat that takes these objects, wraps SimpleDateFormat but adds thread safety, internally synchronizing its use so we can use them as they naturally are much of the time, as constants.

Internally, our three classes can use Calendar since it technically supports most of what you’d want to do. We want them to be easy to use, so lets hide the
nastiness in Calendar when it comes to representing months and days. So let’s use enums to represent MONTH and DAY_OF_WEEK.

Now this really starts to take shape. We can add all our getters and our math methods as appropriate to each class. Time and DateTime have addMillis, addSeconds, addHours and even clearMillis, clearThousandths, clearSeconds. Date and DateTime have addDays, addMonths, addYears, firstDay, lastDay, and the extremely useful isLastOccurenceOfDayOfWeekInMonth (e.g. is this the last Friday of the month).

And of course they implement Comparable, implement hashCode and equals properly so these can be used as keys and have natural sorting order and be used in Sets.

A simplified class diagram is shown below:

Free for Use

Since we think our date classes are very useful for the most common cases and are cleaner than Joda time and other alternatives, we’ve decided to make the code available under the MIT licence. ┬áThis leaves you free to do virtually anything you like to the code, including try to sell it if you feel so inclined.

Source and binary download page

If you find any bugs or have questions, leave a comment here or on the sourceforge project site.

2 thoughts on “Designing a Date/Calendar alternative


  1. The other great thing about our library is its simplicity. It doesn’t try to solve too many problems, enabling us to keep this lib to 4 classes and 2 enums.

  2. Pingback: Files and Directories in the JDK | Carfey Software Blog

Leave a Reply

Your email address will not be published. Required fields are marked *


five + = 10

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>