我正在努力仔细地仔细清理我的一些旧的(生产)代码。我要做的一件事是将java.util.Date
的所有用法转换为LocalDate
和DateTime
。
然而,当我工作时,我注意到今晚有一个很大的障碍。我有这个代码:
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;
}
我将last
和next
转换为:
LocalDate last = new LocalDate(results.getDate("LAST_DELIVERY_DATE"));
LocalDate next = new LocalDate(results.getDate("NEXT_DELIVERY_DATE"));
和Netbeans强调if == null
并说:
Unnecessary test for null - the expression is never null
这是有道理的,因为新的LocalDate
实例不会为空(没有new Object()
可以)。
但是,在这种情况下,在整个程序中的许多情况下,null
日期会传达一些重要信息。在这种情况下,它显示订单1)是否已打开(或未打开),2)是否已收到(或未收到)。
所以,试图找到方法,我想我可以改为使用这段代码:
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"));
但是,这对我来说似乎很难看?另外,它会两次调用“ResultSet#getDate()”函数,如果我错了,请纠正我......对数据库进行两次调用,对吗?所以,现在将我的代码转换为joda-time,我基本上将从数据库中获取java.sql.Date
个对象的时间加倍......
LocalDate last = LocalDate.fromDateFields(results.getDate("LAST_DELIVERY_DATE"));
LocalDate next = LocalDate.fromDateFields(results.getDate("NEXT_DELIVERY_DATE"));
也不起作用,因为fromDateFields
在获得NullPointerException
值时会抛出null
。
所以,我的问题是:当你的程序需要 null日期和joda-time时,你如何最好地处理空日期?我错过了什么吗?是否有更简单的方法来完成我所追求的目标?
答案 0 :(得分:24)
使用三元运算符的代码不能精确地简化,因为您两次访问数据库。考虑用这样的方法编写dateutil
库:
LocalDate convertToLocalDate(Date date) {
if(date == null) return null;
return new LocalDate(date);
}
IMO以经常使用的轻量级静态方法为代价来清理此代码是一个很好的交易。
另请考虑不使用Java。例如,在Javascript中你可以使用||
而没有这个问题。我还听说Scala是一种很好的语言,通过更明确地支持Nullable
类型来解决这个问题。只要您正在清理旧代码,也可以正确执行。
答案 1 :(得分:3)
将java.util.Date转换为org.joda.time.LocalDate
public static LocalDate convertUtilDateToLocalDate(Date date) {
if(date==null) return null;
DateTime dt = new DateTime(date);
return dt.toLocalDate();
}