I am trying to carefully and meticulously clean up some of my older (production) code. One thing I am trying to do is convert all my usages of java.util.Date
to LocalDate
and DateTime
.
However, I noticed one big obstacle tonight as I was working. I had this code:
ResultSet results = stmt.executeQuery();
Date last = results.getDate("LAST_DELIVERY_DATE");
Date next = results.getDate("NEXT_DELIVERY_DATE");
boolean received;
if (last == null && next == null) {
received = true; // order is not open
} else if (last == null) {
received = false;
} else {
received = true;
}
I converted last
and next
to:
LocalDate last = new LocalDate(results.getDate("LAST_DELIVERY_DATE"));
LocalDate next = new LocalDate(results.getDate("NEXT_DELIVERY_DATE"));
and Netbeans underlined the if == null
and said:
Unnecessary test for null - the expression is never null
This makes sense, because a new LocalDate
instance won't be null (no new Object()
can be).
BUT, in this case and in many cases throughout my program, a null
date communicates some essential information. In this case, it shows whether the order 1) is open (or not), 2) has been received (or not).
So, trying to find ways around it, I figured I could instead use this code:
LocalDate last = results.getDate("LAST_DELIVERY_DATE") == null? null : new LocalDate(results.getDate("LAST_DELIVERY_DATE"));
LocalDate next = results.getDate("NEXT_DELIVERY_DATE") == null? null : new LocalDate(results.getDate("NEXT_DELIVERY_DATE"));
But, this just seems ugly to me? Plus, it calls the "ResultSet#getDate()" function twice, which.... correct me if I'm wrong... makes two calls to the database, right?. So, now to convert my code to joda-time I am essentially doubling the time it takes to get java.sql.Date
objects from the database...
LocalDate last = LocalDate.fromDateFields(results.getDate("LAST_DELIVERY_DATE"));
LocalDate next = LocalDate.fromDateFields(results.getDate("NEXT_DELIVERY_DATE"));
doesn't work, either, because fromDateFields
throws a NullPointerException
when it gets a null
value.
So, my question is: how do you best handle null dates when your program necessitates having null dates and joda-time? Am I missing something? Is there an easier way to accomplish what I'm after?
Your code using the ternary operator cannot be that terse precisely because you make two trips to the database. Consider writing a dateutil
library with a method like this:
LocalDate convertToLocalDate(Date date) {
if(date == null) return null;
return new LocalDate(date);
}
IMO making this code clean up at the expense of an often used lightweight static method is a good trade.
Also consider not using Java. In Javascript you could just use ||
and not have this problem, for instance. I also hear Scala is a good language that solves this with more explicit support for Nullable
types. As long as you're cleaning up old code, may as well do it right.