How to compare LocalDate instances Java 8
Asked Answered
E

4

91

I am writing an app that needs to be quite accurate in dates and I wonder how can I compare LocalDate instances.. for now I was using something like:

LocalDate localdate1 = LocalDate().now();
LocalDate localdate2 = someService.getSomeDate();
localdate1.equals(localdate2);

But I noticed that my app is giving me some confusing results, and I think it is because of the date comparing.

I am thinking about obtaining the time from 1970' in long and compare those two, but I must be easier, I am sure of it

Eldrida answered 22/3, 2015 at 23:24 Comment(4)
What kind of confusing results? The dox for equals say "Compares ... ensuring that the date is the same" . That sounds like the right thing in your case.Sulfamerazine
It was my mistake, the source of the problem laid in something another, however I am still curious if this is an appropriate manner to compare LocalDates :)Eldrida
As for your idea of using a count-from-epoch of 1970, avoid doing that. It is confusing and difficult to debug. The modern java.time classes eliminate any need for such awkward handling.Robber
For many purposes I would prefer isEqual(). If both of your objects are LocalDate, it will give you the same result as equals(), which is what you want. If one happens to be a date in another calendar system (say, Hijri), equals() will yield false, and isEqual() will still correctly detect whether the two dates denote the same day.Brassbound
G
134

Using equals() LocalDate does override equals:

int compareTo0(LocalDate otherDate) {
    int cmp = (year - otherDate.year);
    if (cmp == 0) {
        cmp = (month - otherDate.month);
        if (cmp == 0) {
            cmp = (day - otherDate.day);
        }
    }
    return cmp;
}

If you are not happy with the result of equals(), you are good using the predefined methods of LocalDate.

Notice that all of those method are using the compareTo0() method and just check the cmp value. if you are still getting weird result (which you shouldn't), please attach an example of input and output

Geometrid answered 22/3, 2015 at 23:38 Comment(5)
"will give compare the objects" I find this hard to understand, what do you mean by this? How is LocalData.equals different from LocalDate.isEqual? Your answer could use a bit more explanation.Sulfamerazine
@Sulfamerazine you may check my updated answer. i've removed previous edit and added some more informationGeometrid
"all of those method are using the compareTo0() method." That's interesting! Does that mean that equals, isEqual and compareTo(other) == 0 are equivalent? The documentation is a bit unclear.Sulfamerazine
equals and isEquals both using return compareTo0((LocalDate) obj) == 0; so yes. the diff is that equals first check instanceOf while isEqual is strong typed to ChronoLocalDateGeometrid
@Sulfamerazine @Geometrid I just wanted to state that equals() accept an Object and will return false if you pass anything which is not an instance of LocalDate.Dress
T
6
LocalDate ld ....;
LocalDateTime ldtime ...;

ld.isEqual(LocalDate.from(ldtime));
Tetrahedral answered 3/4, 2019 at 11:37 Comment(1)
Welcome to Stack Overflow! Even though this may answer the question, there is no explanation of your code. Please update your answer to provide an explanation of what you are doing. Thanks!Softy
R
0

I believe this snippet will also be helpful in a situation where the dates comparison spans more than two entries.

static final int COMPARE_EARLIEST = 0;

static final int COMPARE_MOST_RECENT = 1;


public LocalDate getTargetDate(List<LocalDate> datesList, int comparatorType) { 
   LocalDate refDate = null;
   switch(comparatorType)
   {
       case COMPARE_EARLIEST:         
       //returns the most earliest of the date entries
          refDate = (LocalDate) datesList.stream().min(Comparator.comparing(item -> 
                      item.toDateTimeAtCurrentTime())).get();
          break;

       case COMPARE_MOST_RECENT:
          //returns the most recent of the date entries 
          refDate = (LocalDate) datesList.stream().max(Comparator.comparing(item -> 
                    item.toDateTimeAtCurrentTime())).get();
          break;
   }

   return refDate;
}
Rocca answered 13/6, 2018 at 18:4 Comment(3)
@Chan Tan: Thanks for the edit, need some little while to acclamatize with the content editor formattings..Rocca
This code is fragile. I wouldn't recommend using it. In particular, if it happened to be running while the local date transitioned from one day to the next, the use of toDateTimeAtCurrentTime would be problematic.Paxton
Method toDateTimeAtCurrentTime does not exist in LocalDate class.Pforzheim
F
0

If you need a Comparator for LocalDateTime (e.g. for using it in a TreeMap or a List.sort() operation) you can use following pattern:

public class BeanWithSortableLocalDateField
{
    public static Comparator<BeanWithSortableLocalDateField> getLocalDateComparator()
    {
        return Comparator.comparingLong( m -> m.localDateField.toEpochDay() );
    }

    private LocalDate localDateField;
}

and use it:

    list.sort( BeanWithSortableLocalDateField.getLocalDateComparator() );
Fabrizio answered 18/3 at 15:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.