pierwszaData.compareTo(drugaData) == -1

0

Cześć. Mam taki problem, porównuje ze sobą dwie daty i wg opisu metody compareTo, metoda powinna zwracać 0, kiedy obiekty są równe, natomiast zwraca -1 dla tych samych dat, a 1 dla daty o dzień późniejszej.

Jak widać na obrazku dzisiejsza data to "2020-12-14", a data w obiekcie offeredRide to również "2020-12-14", mimo to, po porównaniu metodą compareTo wynik to -1

    @Override
    public List<OfferedRide> getListOfOfferedRidesOfSpecificUserBeforeCurrentMoment(int userID) {
        List<OfferedRide> listOfOfferedRideBySpecificUser = getListOfOfferedRidesOfSpecificUser(userID);
        List<OfferedRide> listOfAlreadyDoneOfferedRides = new ArrayList<>();
        Date date = new java.sql.Date(System.currentTimeMillis());
        Time time = new Time(System.currentTimeMillis());
        for (OfferedRide off:
             listOfOfferedRideBySpecificUser) {
            int resultOfComparision = off.getDate_of_ride().compareTo(date);
            if(resultOfComparision == -1){
                listOfAlreadyDoneOfferedRides.add(off);
            } else if (resultOfComparision == 0){
                if(off.getTime_of_ride().compareTo(time) == -1){
                    listOfAlreadyDoneOfferedRides.add(off);
                }
            }
        }
        return listOfAlreadyDoneOfferedRides;
    }

Wiecie może w czym jest problem ? Jak porównywać dwie daty SQLowe ?

0

Oki, mam juz pierwszy trop, mianowicie obiekt date tworzony przy uzyciu System.currentTimeInMillis to = 2020-12-14T1404.637+0100, natomiast w obiekcie OfferedRide obiekt date to 2020-12-14T0000.000+0100

Teraz pytanie jak wyzerować godzinę w obiekcie date

0

Zgłaszam swoją kandydaturę do konkursu "najpaskudniejsze rozwiązanie, które działa"

    @Override
    public List<OfferedRide> getListOfOfferedRidesOfSpecificUserBeforeCurrentMoment(int userID) {
        List<OfferedRide> listOfOfferedRideBySpecificUser = getListOfOfferedRidesOfSpecificUser(userID);
        List<OfferedRide> listOfAlreadyDoneOfferedRides = new ArrayList<>();
        Date date = new java.sql.Date(System.currentTimeMillis());
        Date date2 = Date.valueOf(date.toString());
        Time time = new Time(System.currentTimeMillis());
        Time time2 = Time.valueOf(time.toString());**
        for (OfferedRide off:
             listOfOfferedRideBySpecificUser) {
            int resultOfComparision = off.getDate_of_ride().compareTo(date2);
            if(resultOfComparision == -1){
                listOfAlreadyDoneOfferedRides.add(off);
            } else if (resultOfComparision == 0){
                if(off.getTime_of_ride().compareTo(time2) == -1){
                    listOfAlreadyDoneOfferedRides.add(off);
                }
            }
        }
        return listOfAlreadyDoneOfferedRides;
    }
0

@RezyserKinaAkcji:
Te OfferedRide to jakaś encja JPA?

1

@RezyserKinaAkcji: nie ma potrzeby zerować godziny, wystarczy użyć nowego Time API, wyciągnąć LocalDate i porównać z LocalDate.now()

public static int compareToCurrentDate(final Date date) {
    return date.toLocalDate().compareTo(LocalDate.now());
}

Sugeruję poczytać sobie o tym API: https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html
Im szybciej je przyswoisz tym mniej nerwów sobie napsujesz.

EDIT: jeśli potrzebujesz to oczywiście można co porównujesz do czego zmienić.

0

Czy to jest kod produkcyjny? Czy masz możliwość zmiany?
https://stackoverflow.com/questions/2305973/java-util-date-vs-java-sql-date
Zacząłbym od zmiany biblioteki jeśli chodzi o date. Polece klasykiem:
java.time.*
|
|-> java.time.LocalDate
|-> java.time.LocalDateTime

2

@RezyserKinaAkcji lecimy z tym koksem

  1. Nie używa się jakiś java.sql.Date/java.sql.Time i innych tworów jak jest java time api :/. JPA to obsługuje

  2. Date date = new java.sql.Date(System.currentTimeMillis());
    Tak się nie robi. Nie robi się w kodzie bezpośrednio var date = LocalDate.now(), ani żadnych = new Timestamp() itp.
    Korzysta się z TimeProvidera
    Przy czym to tak naprawde data powinna być pobrana w warstawie sewisu biznesowego, a jakies DAO powinno mieć datę w argumencie metody

  3. "Bo w encji odwzorowuję bazę 1:1 " - WUT? Jak masz w bazie danych date_of_ride to robisz pole w Javie dateOfRide i dodajesz adnotacje @Column("date_of_ride") a nawet chyba nie koniecznie bo Hibernate sam odwzoruje snake_case na camellCase

  4. I najważniejsze, na ile chciało mi się wczytać ten kod to tą cała ifologie powinieneś wywalić i oddelegować to JPA/Spring Data, coś w stylu:
    Select * from rides where user_id = ? and date_of_ride < ?

Time Provider:

   public interface NowProvider {

    LocalDateTime now();

    LocalDate today();
  }

  @Component
  public final class ZoneTimeProvider implements NowProvider {

    public static final String DEFAULT_ZONE_NAME = "Europe/Warsaw";
    public static final ZoneId DEFAULT_ZONE = ZoneId.of(DEFAULT_ZONE_NAME);

    @Override
    public LocalDateTime now() {
        return LocalDateTime.now(DEFAULT_ZONE);
    }

    @Override
    public LocalDate today() {
        return now().toLocalDate();
    }
  }


1 użytkowników online, w tym zalogowanych: 0, gości: 1