-4

Given two Date objects that include hours and minutes, how can I elegantly find out which one of them has the earliest time of the day?

E.g. if date1 is 2018-01-01 at 09:00, and date2 is 2018-01-02 at 08:00, then per this specification, date2 < date1.

Salvatore Iovene
  • 2,064
  • 1
  • 17
  • 31
  • 2
    Please try to avoid using the legacy `java.util.Date` class. You should instead look at the `java.time` package and select the class that is most appropriate for your use case. – Joe C Oct 26 '18 at 22:01
  • `Date` does not contain any hours or minutes. It simply contain a `long` value that is milliseconds since January 1, 1970, 00:00:00 GMT. – tsolakp Oct 26 '18 at 22:01
  • Unfortunately the API I use returns a `java.util.Date` and I cannot change that. Surely there is some conversion that can happen? Or a way to keep the time but reset the year/month/day at the same values for both, and then use `before`? – Salvatore Iovene Oct 26 '18 at 22:06
  • Shame that this question is being down-voted, because it's hard to find an answer to this online. – Salvatore Iovene Oct 26 '18 at 22:49
  • @SalvatoreIovene Converting `Date` to `Instant`, adjusting `Instant` from UTC to a time zone to get a `ZonedDateTime`, and extracting a `LocalTime` from a `ZonedDateTime`, and comparing `LocalTime` objects, are all topics that have been covered many many times already on Stack Overflow. – Basil Bourque Oct 27 '18 at 03:45
  • @BasilBourque but you are describing the solution, and the fact that you need the things that you listed to achieve the desired result is not obvious from a google search similar to the title and contents of my question. – Salvatore Iovene Oct 27 '18 at 08:22
  • Similar to, but quite duplicate of: [*Compare only the time portion of two dates, ignoring the date part*](https://stackoverflow.com/q/7676149/642706) – Basil Bourque Oct 27 '18 at 23:40
  • @SalvatoreIovene You are correct. I have not been able to find any original Question worthy of making this one a duplicate. If you edit your Question, I will retract my down-vote. – Basil Bourque Oct 28 '18 at 00:36

4 Answers4

5

You can use the compareTo-Method of LocalTime if you convert the Date before.

Convert like this (found at https://www.baeldung.com/java-date-to-localdate-and-localdatetime):

public static LocalTime convertToLocalTimeViaInstant(Date dateToConvert) {
    return dateToConvert.toInstant()
            .atZone(ZoneId.systemDefault())
            .toLocalTime();
}

and compare like this:

time1.compareTo(time2);

If u want to use a method u can use the conversion like this:

public static int compareTimeOfDates(Date date1, Date date2) {
    return convertToLocalTimeViaInstant(date1).compareTo(convertToLocalTimeViaInstant(date2));
}
csalmhof
  • 1,820
  • 2
  • 15
  • 24
  • 3
    @SalvatoreIovene I don't think this is missing the point. It converts your Date objects into LocalTime objects that you can compare. The only piece missing is that the resulting LocalTime objects could have non-zero seconds or nanoseconds, but that shouldn't matter. – David Conrad Oct 26 '18 at 22:30
  • in your answer u convert exactly the same way. If u convert directly to LocalTime u can use directly the compareToMethod of this class. – csalmhof Oct 26 '18 at 22:31
  • @SalvatoreIovene If you prefer, you can call the getHour() and getMinute() accessors on the LocalTime objects and compare. The result should be the same. – David Conrad Oct 26 '18 at 22:32
  • 1
    You can do `truncateTo(ChronoUnit.MINUTES)` or `withSecond(0).withNano(0)` on both `LocalTime` objects before comparing, if you wish to exclude these from the comparison. – Erwin Bolwidt Oct 26 '18 at 22:52
0

You can try to do something like:

boolean compareTime(Date date1, Date date2) {
    DateFormat df = new SimpleDateFormat("HHmm");
    int timeDate1 = Integer.valueOf(df.format(date1));
    int timeDate2 = Integer.valueOf(df.format(date2));
    return timeDate1 >= timeDate2;
}
  • FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Oct 27 '18 at 05:21
  • @Basil Bourque - topicstarter mentioned in one of the comments that java.util.Date is returned from the third-party API which he cannot change. – Oleksandr Bereziuk Oct 28 '18 at 13:47
  • Convert using new methods added to the old classes: [`java.time.Date::toInstant()`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html) then call `Instant::atZone` and call `ZonedDateTime::toLocalTime`. – Basil Bourque Oct 28 '18 at 17:45
-2

Edit 2:

//just a sample. base on your case, set the date you have to here.
        Date date1 = Calendar.getInstance().getTime(); 
        Date date2 = Calendar.getInstance().getTime();

        LocalDateTime lcdate1 = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime lcdate2 = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();


        int date1Hour = lcdate1.getHour();
        int date1Minute = lcdate1.getMinute();

        int date2Hour = lcdate2.getHour();
        int date2Minute = lcdate2.getMinute();

More detail is here: https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html

Hope this help.

Kenny Tai Huynh
  • 1,464
  • 2
  • 11
  • 23
-2
int compareTimeOfDate(Date a, Date b) {
    LocalDateTime localA = a.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    int hourA = localA.getHour();
    int minuteA = localA.getMinute();

    LocalDateTime localB = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    int hourB = localB.getHour();
    int minuteB = localB.getMinute();

    if (hourA == hourB && minuteA == minuteB) {
        return 0;
    }

    if (hour1 < hour2 || hour1 == hour2 && minute1 < minute2) {
        return -1;
    }

    return 1;
}
Salvatore Iovene
  • 2,064
  • 1
  • 17
  • 31