Dating advice
One of the stickier points about working in Java is when working with Dates. In the beginning, Java came with a very handy java.util.Date class for representing dates and times.
Somewhere along the way it was decided that Date wasn’t good enough because it doesn’t support internationalization very well. Fine, I say…fix it to better support internationalization. But instead of fixing Date, the whiz-kids at Sun decided to create a branch new class called Calendar and to deprecate all of the truly useful methods in Date.
The main problem with that is that the Calendar class sucks. I won’t go into all of the reasons why it sucks, but trust me, it does. If you don’t believe me, try using it.
Meanwhile a lot of Java’s other APIs, such as JDBC, still work with java.util.Date (or its subclass, java.sql.Date). A result set, for example, has a getDate() method that returns java.sql.Date which has all of its useful methods deprecated.
This date fiasco has led to code that resembles the following:
rs = pst.getResultSet();
while (rs.next()) {
int tempAssignCutoffMonth = rs.getDate(4).getMonth() + 1;
java.util.Calendar cal = new java.util.GregorianCalendar();
int currentMonth = cal.get(java.util.Calendar.MONTH) + 1;
if (currentMonth != tempAssignCutoffMonth) {
// do something important here
}
}
Here we’re working through a result set, checking to see if today’s date is the same as some date pulled from the database. If it’s not, then perform some important logic of some sort.
The first line within the while loop tries to get the month from the Date in the result set and normalize it (getMonth() returns a 0-based value where 0 is January and 11 is December). The normalization is unnecessary because they also normalize what they compare it with. Nevertheless, getMonth() is one of those useful-but-deprecated methods on the Date class. It will still work, sure…but I am allergic to warning messages, so I’d like to find an alternative.
Meanwhile, the developer of this code has given in to the pressure to use Calendar to get the current date. From there he retrieves the month and normalizes it before doing the comparison.
As I see it, there are two problems here:
- ResultSet.getDate() returns a Date object, but Date’s getMonth() method is deprecated.
- Calendar is used and Calendar sucks.
Fortunately, there is a solution. But we’ll have to look beyond the core Java APIs and use the Joda DateTime library. Joda’s a wonderful library that gives us a lot of the power of Calendar, but without the suck-fest that Calendar also offers.
Since we’re dealing with the date at the granularity of a month, I chose to employ Joda’s DateMidnight class (it’s like DateTime, but with the time element set to midnight). That gives me this new snippet of code:
rs = pst.getResultSet();
while (rs.next()) {
DateMidnight cutoffDate = new DateMidnight(rs.getDate(CUTOFF_DATE).getTime());
DateMidnight today = new DateMidnight();
if (today.getMonth() != cutoffDate.getMonth()) {
// do something important here
}
}
ResultSet’s getDate() method still gives me a Date object, but I only use it long enough to call its (not deprecated) getTime() method to get the number of milliseconds since the epoch. I use that value to construct a DateMidnight object. I then use DateMidnight’s default constructor to get today’s date.
Also notice that I replaced the mysterious “4″ parameter to getDate() with a constant that gives me some clue as to what date we’re pulling from the result set.
Then I can compare the months of each date by calling their (not deprecated) getMonth() method. Not only do I no longer get any compiler/IDE warnings, but I also have cleaner, easier-to-read code.
As a side note to this post, I’d like to mention that I found this by chasing down some warnings in my IDE. A lot of times we developers ignore warnings. Errors we take seriously, but warnings go all but unnoticed. In this case the warning was for the deprecated Date methods. I could’ve left it alone, but I chose to fix it instead.
The point to be made is that you should follow those warnings…often times they lead to something worth fixing. Even if they don’t, then by fixing them you remove some noise in your IDE, thereby allowing you to better find those problems that are more serious. Don’t ignore warnings.
