Reputation: 19847
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?
Upvotes: 235
Views: 385632
Reputation: 79620
Java-8 introduced the modern, java.time
Date-Time API which supplanted the outdated and error-prone legacy java.util
Date-Time API. Since then it has been highly recommended to switch to the modern API.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to
java.time
(JSR-310) - a core part of the JDK which replaces this project.
java.time
APIUse Date#toInstant
to convert a java.util.Date
object into an java.time.Instant
which represents an instantaneous point on the timeline in the java.time
API. You can derive other java.time
types from an Instant
as per your requirement.
java.time
, the modern Date-Time API:import java.time.*;
java.util.Date first = ...;
java.util.Date second = ...;
// Change the ZoneId as per your requirement e.g. ZoneId.of("Europe/London")
ZoneId zoneId = ZoneId.systemDefault();
LocalDate firstDate = LocalDate.from(first.toInstant().atZone(zoneId));
LocalDate secondDate = LocalDate.from(second.toInstant().atZone(zoneId));
return firstDate.compareTo(secondDate);
Learn more about the modern Date-Time API from Trail: Date Time.
Upvotes: 2
Reputation: 49
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:
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
}
`
Upvotes: 1
Reputation: 545
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.
Upvotes: 0
Reputation: 498
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));
}
Upvotes: 0
Reputation: 3147
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
}
}
Upvotes: 6
Reputation: 1503859
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
Upvotes: 228
Reputation: 108
// 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)
}
Upvotes: 0
Reputation: 2058
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)));
}
Upvotes: 0
Reputation: 170
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);
Upvotes: 5
Reputation: 414
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. ;)
Upvotes: 0
Reputation: 2699
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.
Upvotes: 3
Reputation: 340230
myJavaUtilDate1.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
.isEqual (
myJavaUtilDate2.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
)
Avoid the troublesome old legacy date-time classes such as Date
& Calendar
, now supplanted by the java.time classes.
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
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.
Upvotes: 18
Reputation: 86389
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.time
classesI 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
.
If you cannot use java 8, there are two options:
Calendar
or SimpleDateFormat
.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.
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 to ThreeTen Backport, the backport of the Java 8 date and time classes to Java 6 and 7: http://www.threeten.org/threetenbp/.
Upvotes: 1
Reputation: 1840
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!
Upvotes: 1
Reputation: 1226
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.
Upvotes: 0
Reputation: 6351
Using Apache commons you can do:
import org.apache.commons.lang3.time.DateUtils
DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)
Upvotes: 0
Reputation: 3403
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);
Upvotes: 7
Reputation: 1251
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
Upvotes: 4
Reputation: 1832
In Java 8 you can use LocalDate which is very similar to the one from Joda Time.
Upvotes: 3
Reputation: 1
How about DateUtil.daysBetween()
. It's Java and it returns a number (difference in days).
Upvotes: -3
Reputation: 41
`
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);
`
Upvotes: 4
Reputation: 11
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));
}
Upvotes: 1
Reputation: 309
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.
Upvotes: 19
Reputation: 887
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
}
Upvotes: 6
Reputation: 22867
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
Upvotes: 9
Reputation: 41
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.
Upvotes: 4
Reputation: 12737
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
}
Upvotes: 143
Reputation: 1
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 }
Upvotes: -3
Reputation:
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);
}
}
Upvotes: 59
Reputation: 1954
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());
Upvotes: 0