233

I would like to have a compareTo method that ignores the time portion of a java.util.Date. I guess there are a number of ways to solve this. What's the simplest way?

Maksim
  • 16,635
  • 27
  • 94
  • 135
Arne Evertsson
  • 19,693
  • 20
  • 69
  • 84

33 Answers33

226

Update: while Joda Time was a fine recommendation at the time, use the java.time library from Java 8+ instead where possible.


My preference is to use Joda Time which makes this incredibly easy:

DateTime first = ...;
DateTime second = ...;

LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();

return firstDate.compareTo(secondDate);

EDIT: As noted in comments, if you use DateTimeComparator.getDateOnlyInstance() it's even simpler :)

// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);

("Use Joda Time" is the basis of almost all SO questions which ask about java.util.Date or java.util.Calendar. It's a thoroughly superior API. If you're doing anything significant with dates/times, you should really use it if you possibly can.)

If you're absolutely forced to use the built in API, you should create an instance of Calendar with the appropriate date and using the appropriate time zone. You could then set each field in each calendar out of hour, minute, second and millisecond to 0, and compare the resulting times. Definitely icky compared with the Joda solution though :)

The time zone part is important: java.util.Date is always based on UTC. In most cases where I've been interested in a date, that's been a date in a specific time zone. That on its own will force you to use Calendar or Joda Time (unless you want to account for the time zone yourself, which I don't recommend.)

Quick reference for android developers

//Add joda library dependency to your build.gradle file
dependencies {
     ...
     implementation 'joda-time:joda-time:2.9.9'
}

Sample code (example)

DateTimeComparator dateTimeComparator = DateTimeComparator.getDateOnlyInstance();

Date myDateOne = ...;
Date myDateTwo = ...;

int retVal = dateTimeComparator.compare(myDateOne, myDateTwo);

if(retVal == 0)
   //both dates are equal
else if(retVal < 0)
   //myDateOne is before myDateTwo
else if(retVal > 0)
   //myDateOne is after myDateTwo
bnayagrawal
  • 1,044
  • 3
  • 12
  • 22
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 33
    Altough as Jon says "Use Joda Time" is the basis of almost all SO questions which ask about java.util.Date or java.util.Calendar I always think that firstly is best to give a concrete answer based on the user's question, at least to show how hard can be to do the java way. And after that suggesting using Joda... – JuanZe Jan 26 '10 at 13:37
  • 13
    @JuanZe: That requires working out exactly how to do something properly in a painful API, which is by definition painful. I'd rather spend that time doing something more productive :) – Jon Skeet Jan 26 '10 at 13:54
  • @Jon Skeet - Couldn't you use DateMidnight instead? – MetroidFan2002 Jun 19 '11 at 20:21
  • 1
    @MetroidFan2002: LocalDate is a better option than DateMidnight, as it's more expressive - *and* not all days have a midnight... – Jon Skeet Jun 19 '11 at 20:27
  • 1
    @Jon Skeet - Good point. But, why create the (seemingly) unneeded DateTime instances? LocalDate has the same construction option that uses the ConverterManager, so if the sources are java.util.Date instances that need comparison, couldn't you just create LocalDate instances directly? – MetroidFan2002 Jun 19 '11 at 20:33
  • @MetroidFan2002: Yes, you could do that. I think I would *personally* rather perform one sort of conversion at a time: once from the JRE classes to Joda, and then perform the "get the date from the date/time" conversion separately. Apart from anything else, that makes it easier to tell what's wrong if one of the conversions is giving a bad result. But that's really just personal preference. – Jon Skeet Jun 20 '11 at 05:29
  • @JonSkeet could you elaborate on "not all days have a midnight"? – dertoni Sep 19 '12 at 11:40
  • 2
    @dertoni: Sure - in Brazil, when the clocks go forward due to daylight saving time, that happens at the start of the day... so a clock would read 23:59:58, 23:59:59, 01:00:00, 01:00:01 etc. – Jon Skeet Sep 19 '12 at 12:21
  • 8
    Wouldn't it be better to use [DateTimeComparator.getDateOnlyInstance()](http://joda-time.sourceforge.net/api-release/org/joda/time/DateTimeComparator.html#getDateOnlyInstance()) – Emil Oct 22 '12 at 10:11
  • @JonSkeet,@Emil: before using [DateTimeComparator.getDateOnlyInstance()](http://joda-time.sourceforge.net/api-release/org/joda/time/DateTimeComparator.html#getDateOnlyInstance()) you must move "_first_" and "_second_" to the same timezone, if not the comparation will fail. This should do the trick: – Neuquino Aug 21 '13 at 18:33
  • @Neuquino: That seems very odd, as a `LocalDate` doesn't logically *have* a time zone. Indeed the documentation explicitly states: "This chronology will be set internally to be in the UTC time zone for all calculations." – Jon Skeet Aug 21 '13 at 19:12
  • 1
    @JonSkeet This should do the trick: return DateTimeComparator.getDateOnlyInstance().compare(first.toInstant(), second.toInstant()); – Neuquino Aug 21 '13 at 19:15
  • @Neuquino: But why would you need to? The two dates would need to be in the same *calendar system* but I can't see how the time zone is a problem. – Jon Skeet Aug 21 '13 at 19:27
  • 1
    Note that `DateTimeComparator.compare()` can take Java `Date` objects, so you don't even have to convert your dates. – Charles Wood Feb 01 '16 at 15:48
  • @CharlesWood: Well you need to do *something* with them, in order to effectively remove the time portions. I think the clearest course of action is to convert them to `LocalDate` values. – Jon Skeet Feb 01 '16 at 15:51
  • Sorry, to be clear: when calling `return DateTimeComparator.getDateOnlyInstance().compare(first, second);`, the variables `first` and `second` can be Java `Date` objects. They don't have to be converted to JodaTime classes to be compared by the JodaTime DateTimeComparator. – Charles Wood Feb 01 '16 at 15:56
  • @CharlesWood: Right, yes, I see what you mean. – Jon Skeet Feb 01 '16 at 15:56
  • FYI, the [Joda-Time](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. – Basil Bourque Mar 25 '17 at 03:40
  • @BasilBourque: Yup - will add something at the top of this answer. – Jon Skeet Mar 25 '17 at 06:28
  • @JonSkeet thanks for the update at the top of the answer, but an example would be more helpful. – Zonker.in.Geneva Dec 19 '19 at 09:24
  • @JonSkeet "not all days have a midnight." Despite your example of daylight savings in Brazil, wouldn't DateMidnight still generate a valid, albeit "non-existent", midnight for that date? I know that creating a date of 30 Feb will always fail, but would creating/calculating a midnight for that DST date also fail? – Zonker.in.Geneva Dec 19 '19 at 09:30
  • @jonSkeet and, of course, with no regards to programmers, Brazil has dropped daylight savings time starting in 2020..... – Zonker.in.Geneva Dec 19 '19 at 09:31
  • @JonSkeet No is asking you to go back over *all* your posts. You already came back to this post and made an update. Of all my searches for "compare dates without time", none of them focused on java.time, but they all mentioned joda. I'm just saying, that if you already bothered to post that update, it would have been more useful to re-answer the question taking into account your new info. I'm still searching for "compare dates without time component using java.time" and not quickly finding a definitive answer. – Zonker.in.Geneva Dec 19 '19 at 13:30
  • @Zonker.in.Geneva: If you think that would be useful, I suggest you take the time to do so yourself then. I don't have the time to do so now. – Jon Skeet Dec 19 '19 at 17:56
141

Apache commons-lang is almost ubiquitous. So what about this?

if (DateUtils.isSameDay(date1, date2)) {
    // it's same
} else if (date1.before(date2)) {
   // it's before
} else {
   // it's after
}
Viacheslav Dobromyslov
  • 3,168
  • 1
  • 33
  • 45
André
  • 12,497
  • 6
  • 42
  • 44
  • Version 2.6 included a truncatedCompareTo function http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/DateUtils.html#truncatedCompareTo%28java.util.Calendar,%20java.util.Calendar,%20int%29 – shonky linux user Jul 21 '13 at 02:16
  • 3
    Sadly doesn't tolerate null dates – Pavel Niedoba Jun 30 '15 at 22:15
  • Guys, nowadays we have Java 8 http://stackoverflow.com/a/35411693/259237 – André Nov 25 '16 at 11:01
  • I not recommend the use of before this way because if the first or the second Date object was donwcasted from Timestamp and have mileseconds, and the another is a normal a Date object you will have trouble because, Date from datestamp store in a different part the of object the miliseconds give differences even when the both dates are equal. – Zini Mar 07 '18 at 18:26
  • Unfortunately, Apache it's not on more than 1.3 billion Android devices, and it's a huge library to depend on for only one use-case. I'll need something else :/ – milosmns Mar 12 '19 at 16:02
59

If you really want to use the java.util.Date, you would do something like this:

public class TimeIgnoringComparator implements Comparator<Date> {
  public int compare(Date d1, Date d2) {
    if (d1.getYear() != d2.getYear()) 
        return d1.getYear() - d2.getYear();
    if (d1.getMonth() != d2.getMonth()) 
        return d1.getMonth() - d2.getMonth();
    return d1.getDate() - d2.getDate();
  }
}

or, using a Calendar instead (preferred, since getYear() and such are deprecated)

public class TimeIgnoringComparator implements Comparator<Calendar> {
  public int compare(Calendar c1, Calendar c2) {
    if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) 
        return c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);
    if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) 
        return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
    return c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH);
  }
}
mtyson
  • 8,196
  • 16
  • 66
  • 106
Jorn
  • 20,612
  • 18
  • 79
  • 126
  • 1
    In the second method you forgot to update some of your references, from d1, d2 to c1, c2. – stivlo Jun 22 '11 at 16:47
  • 1
    After fixing that detail your code works well: I've extensively unit tested it. I've added the step to create a Calendar from the dates, and used your code in my newly created github project [org.obliquid.helpers](https://github.com/stivlo/org.obliquid.helpers), thanks. – stivlo Jun 22 '11 at 18:00
  • Sweet, nice solution without use any external library. – 4gus71n Nov 06 '13 at 16:06
  • 1
    All of these methods are deprecated. Can this have any kind of impact? – Pranav Mahajan Jun 18 '15 at 06:07
34

My preference would be to use the Joda library insetad of java.util.Date directly, as Joda makes a distinction between date and time (see YearMonthDay and DateTime classes).

However, if you do wish to use java.util.Date I would suggest writing a utility method; e.g.

public static Date setTimeToMidnight(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( date );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}
Adamski
  • 54,009
  • 15
  • 113
  • 152
  • 1
    Joda-Time YearMonthDay is deprecated in favour of LocalDate. Also, the code on calendar will have issues if the time zone doesn't have midnight 00:00 due to daylight savings. – JodaStephen Sep 18 '09 at 08:02
  • 1
    This doesn't work 100% of the time. Had a use case where I did that and the calendar.getTime() would still return the time with the hours set as the parameter date. Best to clear the fields and set only the year, month and day ones. – Jonathan Drapeau Nov 07 '16 at 18:39
33

Any opinions on this alternative?

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
Robert Brown
  • 10,888
  • 7
  • 34
  • 40
  • 1
    I don't think that would work, even if converting to Strings was a good idea. The `==` operator doesn't necessarily return `true` for equivalent Strings (use `equals()`). You certainly can't use the other comparison operators you mentioned, either. – harto Nov 11 '09 at 00:55
  • 1
    Ahh yes - my ruby is ruining my Java! Could convert the strings to ints though for <, > etc. – Robert Brown Nov 11 '09 at 03:01
  • Using Joda is the sound way, but this is elegant! – Arne Evertsson Nov 11 '09 at 09:19
  • This won't work for everyone, but it's very simple and lightweight; a good alternative when other libs aren't available. – Jacob Marble Oct 04 '11 at 23:02
  • For getting the order of the dates, you may also use `sdf.format(date1).compareTo(sdf.format(date2));`. – Ole V.V. Mar 24 '17 at 22:51
19

If you want to compare only the month, day and year of two dates, following code works for me:

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));

Thanks Rob.

eatSleepCode
  • 4,427
  • 7
  • 44
  • 93
Dellanio
  • 309
  • 3
  • 4
16

tl;dr

myJavaUtilDate1.toInstant()
               .atZone( ZoneId.of( "America/Montreal" ) )
               .toLocalDate()
               .isEqual (
                   myJavaUtilDate2.toInstant()
                                  .atZone( ZoneId.of( "America/Montreal" ) )
                                  .toLocalDate()
               )

Avoid legacy date-time classes

Avoid the troublesome old legacy date-time classes such as Date & Calendar, now supplanted by the java.time classes.

Using java.time

A java.util.Date represents a moment on the timeline in UTC. The equivalent in java.time is Instant. You may convert using new methods added to the legacy class.

Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();

You want to compare by date. A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" );

Apply the ZoneId to the Instant to get a ZonedDateTime.

ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );

The LocalDate class represents a date-only value without time-of-day and without time zone. We can extract a LocalDate from a ZonedDateTime, effectively eliminating the time-of-day portion.

LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();

Now compare, using methods such as isEqual, isBefore, and isAfter.

Boolean sameDate = localDate1.isEqual( localDate2 );

See this code run live at IdeOne.com.

instant1: 2017-03-25T04:13:10.971Z | instant2: 2017-03-24T22:13:10.972Z

zdt1: 2017-03-25T00:13:10.971-04:00[America/Montreal] | zdt2: 2017-03-24T18:13:10.972-04:00[America/Montreal]

localDate1: 2017-03-25 | localDate2: 2017-03-24

sameDate: false


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
13

I too prefer Joda Time, but here's an alternative:

long oneDay = 24 * 60 * 60 * 1000
long d1 = first.getTime() / oneDay
long d2 = second.getTime() / oneDay
d1 == d2

EDIT

I put the UTC thingy below in case you need to compare dates for a specific timezone other than UTC. If you do have such a need, though, then I really advise going for Joda.

long oneDay = 24 * 60 * 60 * 1000
long hoursFromUTC = -4 * 60 * 60 * 1000 // EST with Daylight Time Savings
long d1 = (first.getTime() + hoursFromUTC) / oneDay
long d2 = (second.getTime() + hoursFromUTC) / oneDay
d1 == d2
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
9

Already mentioned apache commons-utils:

org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DAY_OF_MONTH)

gives you Date object containing only date, without time, and you can compare it with Date.compareTo

Danubian Sailor
  • 1
  • 38
  • 145
  • 223
7

If you're using Java 8, you should use the java.time.* classes to compare dates - it's preferred to the various java.util.* classes

eg; https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html

LocalDate date1 = LocalDate.of(2016, 2, 14);
LocalDate date2 = LocalDate.of(2015, 5, 23);
date1.isAfter(date2);
Lorcan O'Neill
  • 3,303
  • 1
  • 25
  • 24
6

I am afraid there is no method of comparing two dates that could be called "easy" or "simple".

When comparing two time instances with any sort of reduced precision (e.g. just comparing dates), you must always take into account how time zone affects the comparison.

If date1 is specifying an event that occurred in +2 timezone and date2 is specifying an event that occurred in EST, for example, you must take care to properly understand the implications of the comparison.

Is your purpose to figure out if the two events occurred in the same calendar date in their own respective time zones? Or do You need to know if the two dates fall into the same calendar date in a specific time zone (UTC or your local TZ, for example).

Once you figure out what it is actually that You are trying to compare, it is just a matter of getting the year-month-date triple in an appropriate time zone and do the comparison.

Joda time might make the actual comparison operation look much cleaner, but the semantics of the comparison are still something You need to figure out yourself.

Roland Tepp
  • 8,301
  • 11
  • 55
  • 73
6

Simply Check DAY_OF_YEAR in combination with YEAR property

boolean isSameDay = 
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)

EDIT:

Now we can use the power of Kotlin extension functions

fun Calendar.isSameDay(second: Calendar): Boolean {

    return this[Calendar.YEAR] == second[Calendar.YEAR] && this[Calendar.DAY_OF_YEAR] == second[Calendar.DAY_OF_YEAR]
}

fun Calendar.compareDatesOnly(other: Calendar): Int {

    return when {
        isSameDay(other) -> 0
        before(other) -> -1
        else -> 1
    }
}
Simon K. Gerges
  • 3,097
  • 36
  • 34
5

If you just want to compare only two dates without time, then following code might help you:

final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date dLastUpdateDate = dateFormat.parse(20111116);
Date dCurrentDate = dateFormat.parse(dateFormat.format(new Date()));
if (dCurrentDate.after(dLastUpdateDate))
{
   add your logic
}
Pritesh Shah
  • 857
  • 1
  • 7
  • 8
  • That's the same as [Rob's answer](http://stackoverflow.com/a/1712255). I think [Jorn's solution](http://stackoverflow.com/a/1439845) is better since it doesn't involve a round-trip to strings and should accomplish the same thing. – Rup Aug 16 '12 at 11:53
5

I don't know it is new think or else, but i show you as i done

SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yyyy");
Date td_date = new Date();
String first_date = dtf.format(td_date);    //First seted in String 
String second_date = "30/11/2020";          //Second date you can set hear in String

String result = (first_date.equals(second_date)) ? "Yes, Its Equals":"No, It is not Equals";
System.out.println(result);
13hola
  • 170
  • 1
  • 12
4

`

SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy")

   Date date1=sdf.parse("03/25/2015");



  Date currentDate= sdf.parse(sdf.format(new Date()));

   return date1.compareTo(currentDate);

`

zakir
  • 41
  • 1
4

Using http://mvnrepository.com/artifact/commons-lang/commons-lang

Date date1 = new Date();

Date date2 = new Date();

if (DateUtils.truncatedCompareTo(date1, date2, Calendar.DAY_OF_MONTH) == 0)
    // TRUE
else
    // FALSE
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Federico Traiman
  • 1,191
  • 1
  • 13
  • 18
4

Here is a solution from this blog: http://brigitzblog.blogspot.com/2011/10/java-compare-dates.html

long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("Time in days: " + diffDays  + " days.");

i.e. you can see if the time difference in milliseconds is less than the length of one day.

Rup
  • 33,765
  • 9
  • 83
  • 112
wilbert
  • 41
  • 1
  • 1
  • 5
    That sample will check if the two dates are within 24 hours of each other but not necessarily if they're both on the same date, i.e. it's possible to span a midnight. Better would be to instead divide both sets of millis by MILLIS_IN_DAY and compare the result, but that will only be exact for UTC not local times. – Rup Aug 16 '12 at 11:57
3

In Java 8 you can use LocalDate which is very similar to the one from Joda Time.

habsq
  • 1,827
  • 16
  • 17
3
public Date saveDateWithoutTime(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( date );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.HOUR, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}

This will help you to compare dates without considering the time.

Fathima km
  • 2,539
  • 3
  • 18
  • 26
1

Using the getDateInstance of SimpleDateFormat, we can compare only two date object without time. Execute the below code.

public static void main(String[] args) {        
        Date date1  = new Date();
        Date date2  = new Date();
        DateFormat dfg = SimpleDateFormat.getDateInstance(DateFormat.DATE_FIELD);
        String dateDtr1 = dfg.format(date1);
        String dateDtr2 = dfg.format(date2);
        System.out.println(dateDtr1+" : "+dateDtr2);
        System.out.println(dateDtr1.equals(dateDtr2));  

    }
1

Another Simple compare method based on the answers here and my mentor guidance

public static int compare(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.setTime(d1);
    c1.set(Calendar.MILLISECOND, 0);
    c1.set(Calendar.SECOND, 0);
    c1.set(Calendar.MINUTE, 0);
    c1.set(Calendar.HOUR_OF_DAY, 0);
    c2.setTime(d2);
    c2.set(Calendar.MILLISECOND, 0);
    c2.set(Calendar.SECOND, 0);
    c2.set(Calendar.MINUTE, 0);
    c2.set(Calendar.HOUR_OF_DAY, 0);
    return c1.getTime().compareTo(c2.getTime());
  }

EDIT: According to @Jonathan Drapeau, the code above fail some cases (I would like to see those cases, please) and he suggested the following as I understand:

public static int compare2(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.clear();
    c2.clear();
    c1.set(Calendar.YEAR, d1.getYear());
    c1.set(Calendar.MONTH, d1.getMonth());
    c1.set(Calendar.DAY_OF_MONTH, d1.getDay());
    c2.set(Calendar.YEAR, d2.getYear());
    c2.set(Calendar.MONTH, d2.getMonth());
    c2.set(Calendar.DAY_OF_MONTH, d2.getDay());
    return c1.getTime().compareTo(c2.getTime());
}

Please notice that, the Date class is deprecated cause it was not amenable to internationalization. The Calendar class is used instead!

Matrix
  • 1,810
  • 1
  • 19
  • 20
  • This doesn't work 100% of the time. Had a use case where I did that and the calendar.getTime() would still return the time with the hours set as the parameter date. Best to clear the fields and set only the year, month and day ones. – Jonathan Drapeau Nov 07 '16 at 18:39
  • @JonathanDrapeau, it sounds to me like you may have run into a consequence of not picking an explicit time zone. Certainly better make the time zone explicit than use the deprecated `getXxx` methods of `Date`. – Ole V.V. Mar 24 '17 at 22:20
1

First, be aware that this operation depends on the time zone. So choose whether you want to do it in UTC, in the computer’s time zone, in your own favourite time zone or where. If you are not yet convinced it matters, see my example at the bottom of this answer.

Since your question isn’t quite clear about this, I am assuming that you have a class with an instance field representing a point in time and implementing Comparable, and you want the natural ordering of your objects to be by the date, but not the time, of that field. For example:

public class ArnesClass implements Comparable<ArnesClass> {

    private static final ZoneId arnesTimeZone = ZoneId.systemDefault();

    private Instant when;

    @Override
    public int compareTo(ArnesClass o) {
        // question is what to put here
    }

}

Java 8 java.time classes

I have taken the freedom of changing the type of your instance field from Date to Instant, the corresponding class in Java 8. I promise to return to the treatment of Date below. I have also added a time zone constant. You may set it to ZoneOffset.UTC or ZoneId.of("Europe/Stockholm") or what you find appropriate (setting it to a ZoneOffset works because ZoneOffset is a subclass of ZoneId).

I have chosen to show the solution using the Java 8 classes. You asked for the simplest way, right? :-) Here’s the compareTo method you asked for:

public int compareTo(ArnesClass o) {
    LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
    LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
    return dateWithoutTime.compareTo(otherDateWithoutTime);
}

If you never need the time part of when, it is of course easier to declare when a LocalDate and skip all conversions. Then we don’t have to worry about the time zone anymore either.

Now suppose that for some reason you cannot declare your when field an Instant or you want to keep it an old-fashioned Date. If you can still use Java 8, just convert it to Instant, then do as before:

    LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();

Similarly for o.when.

No Java 8?

If you cannot use java 8, there are two options:

  1. Solve it using one of the old classes, either Calendar or SimpleDateFormat.
  2. Use the backport of the Java 8 date and time classes to Java 6 and 7, then just do as above. I include a link at the bottom. Do not use JodaTime. JodaTime was probably a good suggestion when the answers recommending it were written; but JodaTime is now in maintenance mode, so the ThreeTen backport is a better and more futureproof option.

The old-fashioned ways

Adamski’s answer shows you how to strip the time part off a Date using the Calendar class. I suggest you use getInstance(TimeZone) to obtain the Calendar instance for the time zone you want. As an alternative you may use the idea from the second half of Jorn’s answer.

Using SimpleDateFormat is really an indirect way of using Calendar since a SimpleDateFormat contains a Calendar object. However, you may find it less troublesome than using Calendar directly:

private static final TimeZone arnesTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
private static final DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
static {
    formatter.setTimeZone(arnesTimeZone);
}

private Date when;

@Override
public int compareTo(ArnesClass o) {
    return formatter.format(when).compareTo(formatter.format(o.when));
}

This was inspired by Rob’s answer.

Time zone dependency

Why do we have to pick a specific time zone? Say that we want to compare two times that in UTC are March 24 0:00 (midnight) and 12:00 (noon). If you do that in CET (say, Europe/Paris), they are 1 am and 1 pm on March 24, that is, the same date. In New York (Eastern Daylight Time), they are 20:00 on March 23 and 8:00 on March 24, that is, not the same date. So it makes a difference which time zone you pick. If you just rely on the computer’s default, you may be in for surprises when someone tries to run your code on a computer in another place in this globalized world.

Link

Link to ThreeTen Backport, the backport of the Java 8 date and time classes to Java 6 and 7: http://www.threeten.org/threetenbp/.

Community
  • 1
  • 1
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Using Apache commons you can do:

import org.apache.commons.lang3.time.DateUtils

DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)
unify
  • 6,161
  • 4
  • 33
  • 34
0
public static Date getZeroTimeDate(Date fecha) {
    Date res = fecha;
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( fecha );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    res = calendar.getTime();

    return res;
}

Date currentDate = getZeroTimeDate(new Date());// get current date   

this is the simplest way to solve this problem.

rana_sadam
  • 1,216
  • 10
  • 18
0

I solved this by comparing by timestamp:

    Calendar last = Calendar.getInstance();

    last.setTimeInMillis(firstTimeInMillis);

    Calendar current = Calendar.getInstance();

    if (last.get(Calendar.DAY_OF_MONTH) != current.get(Calendar.DAY_OF_MONTH)) {
        //not the same day
    }

I avoid to use Joda Time because on Android uses a huge space. Size matters. ;)

0

Another solution using Java 8 and Instant, is using the truncatedTo method

Returns a copy of this Instant truncated to the specified unit.

Example:

@Test
public void dateTruncate() throws InterruptedException {
    Instant now = Instant.now();
    Thread.sleep(1000*5);
    Instant later = Instant.now();
    assertThat(now, not(equalTo(later)));
    assertThat(now.truncatedTo(ChronoUnit.DAYS), equalTo(later.truncatedTo(ChronoUnit.DAYS)));
}
rince
  • 1,988
  • 1
  • 20
  • 24
0
// Create one day 00:00:00 calendar
int oneDayTimeStamp = 1523017440;
Calendar oneDayCal = Calendar.getInstance();
oneDayCal.setTimeInMillis(oneDayTimeStamp * 1000L);
oneDayCal.set(Calendar.HOUR_OF_DAY, 0);
oneDayCal.set(Calendar.MINUTE, 0);
oneDayCal.set(Calendar.SECOND, 0);
oneDayCal.set(Calendar.MILLISECOND, 0);

// Create current day 00:00:00 calendar
Calendar currentCal = Calendar.getInstance();
currentCal.set(Calendar.HOUR_OF_DAY, 0);
currentCal.set(Calendar.MINUTE, 0);
currentCal.set(Calendar.SECOND, 0);
currentCal.set(Calendar.MILLISECOND, 0);

if (oneDayCal.compareTo(currentCal) == 0) {
    // Same day (excluding time)
}
yaslam
  • 108
  • 7
  • Thanks! There's a handful of other answers with the same approach already though - although I see now you're comparing the Calendar objects directly whereas they largely compare the getTime()s. – Rup Apr 06 '18 at 14:41
0

My proposition:

    Calendar cal = Calendar.getInstance();
    cal.set(1999,10,01);   // nov 1st, 1999
    cal.set(Calendar.AM_PM,Calendar.AM);
    cal.set(Calendar.HOUR,0);
    cal.set(Calendar.MINUTE,0);
    cal.set(Calendar.SECOND,0);
    cal.set(Calendar.MILLISECOND,0);

    // date column in the Thought table is of type sql date
    Thought thought = thoughtDao.getThought(date, language);

    Assert.assertEquals(cal.getTime(), thought.getDate());
Jean-Pierre Schnyder
  • 1,572
  • 1
  • 15
  • 24
0

If you strictly want to use Date ( java.util.Date ), or without any use of external Library. Use this :

public Boolean compareDateWithoutTime(Date d1, Date d2) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    return sdf.format(d1).equals(sdf.format(d2));
}
Raj Shukla
  • 442
  • 5
  • 9
0
    Date today = new Date();
    Date endDate = new Date();//this
    endDate.setTime(endDate.getTime() - ((endDate.getHours()*60*60*1000) + (endDate.getMinutes()*60*1000) + (endDate.getSeconds()*1000)));
    today.setTime(today.getTime() - ((today.getHours()*60*60*1000) + (today.getMinutes()*60*1000) + (today.getSeconds()*1000)));

    System.out.println(endDate.compareTo(today) <= 0);

I am simply setting hours/minutes/second to 0 so no issue with the time as time will be same now for both dates. now you simply use compareTo. This method helped to find "if dueDate is today" where true means Yes.

arjun kumar
  • 467
  • 5
  • 12
0

If you are looking for a simple solution and yet you do not want to change the deprecated java.util.Date class from your project, you can just add this method to your project and continue your quest:

Using java.util.concurrent.TimeUnit

`

public boolean isSameDay(Date first, Date second) {
    long difference_In_Time = first.getTime() - second.getTime();
        // calculate difference in days
        long difference_In_Days = 
        TimeUnit
              .MILLISECONDS
              .toDays(difference_In_Time);
        if (difference_In_Days == 0) {
            return true;
        }
        return false;
    }

`

Implement it like:

`

Date first = ...;
Date second = ...;
if (isSameDay(first, second)) {
    // congratulations, they are the same
}
else {
   // heads up champ, they are not the same
}

`

-2

How about DateUtil.daysBetween(). It's Java and it returns a number (difference in days).

Jonas Czech
  • 12,018
  • 6
  • 44
  • 65
Jules
  • 1
-2

This is what worked for me:

var Date1 = new Date(dateObject1.toDateString()); //this sets time to 00:00:00
var Date2 = new Date(dateObject2.toDateString()); 
//do a normal compare
if(Date1 > Date2){ //do something }
Pops
  • 30,199
  • 37
  • 136
  • 151
  • 2
    Your "normal" compare wouldn't even compile in Java. If it would, it would compare the object references, but this is not allowed. – stivlo Jun 22 '11 at 16:43
  • I edited to add Markdown, but stivlo is right. I have no idea how that code "worked for you." – Pops Nov 09 '11 at 21:34