Преобразование java.sql.Date & java.util.Date в org.joda.time.LocalDate

Я стараюсь тщательно и тщательно очищать некоторые из моих старых (производственных) кода. Одна вещь, которую я пытаюсь сделать, - это преобразовать все мои применения 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 не будет null (no 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.

Итак, мой вопрос: как вы лучше всего обрабатываете нулевые даты, когда ваша программа требует наличия нулевых дат и времени joda? Я что-то упускаю? Есть ли более простой способ выполнить то, что я хочу?

Ответ 1

Ваш код с использованием тернарного оператора не может быть настолько точным, потому что вы делаете две поездки в базу данных. Подумайте о написании библиотеки dateutil с помощью такого метода:

    LocalDate convertToLocalDate(Date date) {
        if(date == null) return null;
        return new LocalDate(date);
    }

IMO, делающий этот код очищенным за счет часто используемого легкого статического метода, является хорошей сделкой.

Также не рассматривайте использование Java. В Javascript вы можете просто использовать || и не иметь этой проблемы, например. Я также слышал, что Scala - хороший язык, который решает эту проблему с более явной поддержкой типов Nullable. До тех пор, пока вы очищаете старый код, вы также можете сделать это правильно.

Ответ 2

Преобразовать 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();
        }