Date Handling in Java Revisited

Posted on February 23, 2005 by Scott Leberknight

After writing last week about how horrendous date handling in Java can be, apparently the developers who just released version 1.0 of Joda Time agreed. But they actually did something about it by creating a Java library that seems to address many of the shortcomings in the default JDK date classes. Pretty cool.

So using Joda Time you can implement the example from my date handling rant as:

DateTime start = new DateTime(2004, 2, 17, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 2, 17, 0, 0, 0, 0);
Period period = new Period(start, end, PeriodType.weeks());
int numberOfWeeks = period.getWeeks();
System.out.println("numberOfWeeks = " + numberOfWeeks);

Well, that's a lot better than using the JDK date classes and close to the simplicity of the Python example. And it prints the correct answer, 52.

I did run into a slight issue at first. Notice in the above example I am using the version of the Period constructor that takes two ReadableInstants and a PeriodType. In this case I wanted to compute weeks so I used PeriodType.weeks() as the value of the argument. There is a constructor that takes only the two ReadableInstants which, according to the JavaDoc, is supposed to use the "standard" PeriodType and should include the "standard set of fields". The standard fields defined in PeriodType include: years, months, weeks, days, hours, minutes, seconds, and millis. Good enough, right?

Well, when I run the following sample code it prints out zero not 52 as I initially expected:

DateTime start = new DateTime(2004, 2, 17, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 2, 17, 0, 0, 0, 0);
Period period = new Period(start, end); // uses standard PeriodType
int numberOfWeeks = period.getWeeks();
System.out.println("numberOfWeeks = " + numberOfWeeks); // prints zero!

In fact, the value of millis, seconds, minutes, hours, days, weeks, and months are all zero. Only year has a value and its value is one. Hmmm. After some more playing around I found out that the way Joda Time computes the period is actually pretty intelligent. Check out the following slightly modified example, which contains dates with different months, day, hour, minute, etc.

DateTime start = new DateTime(2004, 2, 17, 16, 30, 10, 546);
DateTime end = new DateTime(2005, 5, 10, 17, 45, 7, 344);
Period period = new Period(start, end);
System.out.println("period = " + period);

When run this prints: period = P1Y2M3W2DT1H14M56.798S. So it actually is smart enough to break apart the period into years, months, weeks, days, etc. That is pretty cool. And if you query the individual methods such as getDays() you get the values shown in the output string - 1 year, 2 months, 3 weeks, 2 days, 1 hour, 14 minutes, 56 seconds, and 798 milliseconds. So the values in Period must be taken together as defining a period, which makes sense since that is really how people tend to think about dates.

Joda Time also provides Interval and Duration classes in addition to Period. They all do slightly different things. But overall there are a ton of useful utilities in Joda Time and I plan to start using it straightaway on projects.



Post a Comment:
Comments are closed for this entry.