Те же даты, сравниваемые в Java возвращая -1 - PullRequest
0 голосов
/ 09 апреля 2020
try {

        String hql = "SELECT taskDate FROM TaskFutureDates t WHERE t.taskId= : taskId";
        List<java.sql.Date> result = em.createQuery(hql).setParameter("taskId", taskId).getResultList();

        java.sql.Date currentDate =new Date(new java.util.Date().getTime()); 

        if (result.size() != 0) {

            for(java.sql.Date date: result) {

                if(date.compareTo(currentDate)>=0) {

                   System.err.println("CAST= "+(Date) date);
                    return (java.sql.Date) date;
                }

            }
        }

    } catch (Exception e) {
        // TODO: handle exception

        //System.err.println(e);
    }
    return null;

}

когда я сравниваю две даты, я получаю сценарий ошибки ios

1. когда я сравниваю альтернативные дни, я получаю -1 например 09/04/2020 10/04/2020

когда дата такая же, я получаю -1 например 10/04/2020 10/04/2020

во втором сценарии я должен получить 0, почему результат равен -1?

Ответы [ 3 ]

2 голосов
/ 09 апреля 2020

из сравнения. c:

значение меньше 0, если эта Дата предшествует аргументу Дата

today () (= последняя полночь) или, возможно, любая дата из вашей таблицы меньше, чем сейчас () (включая текущее время)

1 голос
/ 10 апреля 2020

tl; dr

Используйте современные java .time классы для извлечения и сравнения сохраненных значений даты с сегодняшней датой.

myResultSet.getObject( … , LocalDate.class ).isAfter( LocalDate.now( "Africa/Tunis" ) ) 

Подробности

Как объяснил правильный ответ Роттвил , вы не должны использовать ужасный класс java.sql.Date. Этот класс был лет go вытесненных современными java .time классами. В частности, java.time.LocalDate.

Начиная с JDB C 4.2, мы можем обмениваться объектами java .time с базой данных. Для столбцов типа сродни стандартному SQL типу DATE используйте setObject, updateObject и getObject для обмена LocalDate объектов.

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

Для получения сегодняшней даты необходим часовой пояс. В любой момент времени дата меняется по всему земному шару в зависимости от часового пояса. Таким образом, хотя это может быть «завтра» в Токио, Япония, оно может быть одновременно «вчера» в Толедо, Огайо, США.

Если вы не укажете часовой пояс, текущий часовой пояс JVM по умолчанию применяется неявно.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
LocalDate today = LocalDate.now( z ) ;

Сравните с использованием методов isEqual, isBefore и isAfter.

Boolean isFuture = ld.isAfter( today ) ;
1 голос
/ 10 апреля 2020

Хотя java.sql.Date считается датой, на самом деле она все еще является тонкой оберткой в ​​течение миллисекунд эпохи. Это не усекает их. Таким образом, два java.sql.Date значения, которые имеют одну и ту же дату, могут по-прежнему иметь два разных значения миллисекунд эпохи (ie проверить результат getTime()), и в результате они не будут сравниваться одинаково.

Реализация конструктора java.sql.Date (Date(long)):

public Date(long date) {
    // If the millisecond date value contains time info, mask it out.
    super(date);

}

Вопреки комментарию, ничего не скрыто. Вероятно, это связано с тем, что java.sql.Date чувствителен к часовому поясу JVM по умолчанию, и попытка его скрыть только усложнит ситуацию.

В любом случае, поскольку Java 8 / JDB C 4.2, он было бы лучше использовать java.time.LocalDate вместо java.sql.Date.

Если вы не можете полностью перейти на использование LocalDate, я бы рекомендовал, по крайней мере, использовать:

LocalDate currentDate = LocalDate.now();
//...
if (date.toLocalDate().compareTo(currentDate) >= 0) {
    // ...
}

Или - как показано в ответе Бэзила Бурка - используйте специальные методы сравнения, такие как isAfter, isBefore и isEqual.

...