Java 如何在没有时间部分的情况下比较两个日期?

Java 如何在没有时间部分的情况下比较两个日期?,java,datetime,Java,Datetime,我想要一个compareTo方法,它忽略java.util.Date的时间部分。我想有很多方法可以解决这个问题。最简单的方法是什么?我更喜欢直接使用java.util.Date的库insetad,因为Joda区分了日期和时间(请参见和类) 但是,如果您确实希望使用java.util.Date,我建议您编写一个实用方法;e、 g public static Date setTimeToMidnight(Date date) { Calendar calendar = Calendar.ge

我想要一个compareTo方法,它忽略java.util.Date的时间部分。我想有很多方法可以解决这个问题。最简单的方法是什么?

我更喜欢直接使用
java.util.Date
的库insetad,因为Joda区分了日期和时间(请参见和类)

但是,如果您确实希望使用
java.util.Date
,我建议您编写一个实用方法;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();
}

更新:虽然Joda Time在当时是一个很好的建议,但尽可能使用Java8+中的库


我的偏好是使用它,这使得这非常容易:

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

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

return firstDate.compareTo(secondDate);
编辑:如注释中所述,如果您使用它,则更简单:)

(“使用Joda Time”是几乎所有关于
java.util.Date
java.util.Calendar
的问题的基础。它是一个非常优秀的API。如果你在日期/时间方面做了任何有意义的事情,你应该尽可能使用它。)

如果您完全被迫使用内置API,则应使用适当的日期和时区创建
Calendar
的实例。然后,您可以将每个日历中的每个字段(小时、分钟、秒和毫秒)设置为0,并比较结果时间。但与Joda解决方案相比,绝对令人讨厌:)

时区部分很重要:
java.util.Date
始终基于UTC。在大多数情况下,如果我对某个日期感兴趣,那就是某个特定时区的日期。这本身将迫使您使用
日历
或Joda时间(除非您想自己解释时区,我不建议这样做)

android开发者的快速参考

//Add joda library dependency to your build.gradle file
dependencies {
     ...
     implementation 'joda-time:joda-time:2.9.9'
}
示例代码(示例)

DateTimeComparator DateTimeComparator=DateTimeComparator.getDateOnlyInstance();
日期myDateOne=。。。;
日期myDateTwo=。。。;
int retVal=dateTimeComparator.compare(myDateOne,myDateTwo);
如果(retVal==0)
//两个日期相同
else if(retVal<0)
//myDateOne在MyDate2之前
否则如果(返回值>0)
//myDateOne在MyDate2之后

如果您真的想使用java.util.Date,您可以这样做:

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();
  }
}
公共类TimeIgnoringComparator实现Comparator{
公共整数比较(日期d1、日期d2){
如果(d1.getYear()!=d2.getYear())
返回d1.getYear()-d2.getYear();
如果(d1.getMonth()!=d2.getMonth())
返回d1.getMonth()-d2.getMonth();
返回d1.getDate()-d2.getDate();
}
}
或者,改用日历(首选,因为getYear()等不推荐使用)

公共类TimeIgnoringComparator实现Comparator{
公共整数比较(日历c1、日历c2){
如果(c1.get(日历年)!=c2.get(日历年))
返回c1.get(日历年)-c2.get(日历年);
if(c1.get(日历月)!=c2.get(日历月))
返回c1.get(日历月)-c2.get(日历月);
返回c1.get(日历月日)-c2.get(日历月日);
}
}
我也喜欢,但这里有一个替代方案:

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

我把UTC的东西放在下面,以防您需要比较UTC以外的特定时区的日期。如果你真的有这样的需要,那么我真的建议你去找乔达

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

恐怕没有什么方法可以比较两个日期,可以称之为“简单”或“简单”

在比较精度降低的两个时间实例时(例如,仅比较日期),必须始终考虑时区对比较的影响

例如,如果
date1
指定的事件发生在+2时区,而
date2
指定的事件发生在EST,则必须注意正确理解比较的含义

您的目的是想知道这两个事件是否发生在各自时区的同一日历日期?或者,您是否需要知道这两个日期是否属于特定时区的同一日历日期(例如UTC或您当地的TZ)

一旦你弄清楚你想要比较的是什么,你只需要在一个合适的时区里把年-月-日的日期增加三倍,然后进行比较


Joda time可能会使实际的比较操作看起来更清晰,但比较的语义仍然需要您自己去弄清楚。

对此备选方案有何看法

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
几乎无处不在。那么这个呢

if (DateUtils.isSameDay(date1, date2)) {
    // it's same
} else if (date1.before(date2)) {
   // it's before
} else {
   // it's after
}
我的主张:

    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());

这就是我的工作原理:

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 }

以下是来自此博客的解决方案:


i、 e.您可以查看以毫秒为单位的时差是否小于一天的长度。

如果您只想比较两个没有时间的日期,则以下代码可能会帮助您:

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
}

如果您只想比较两个日期的月、日和年,以下代码适用于我:

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

谢谢Rob。

已经提到了apache commons utils:

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

为您提供仅包含日期而不包含时间的日期对象,您可以将其与日期进行比较。compareTo

使用SimpleDataFormat的GetDate实例,我们只能比较两个不包含时间的日期对象。执行下面的代码

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));  

    }

只需结合年份属性检查年份的日期

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

现在我们可以使用Kotlin扩展函数的强大功能

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
    }
}
`


`

在Java 8中,您可以使用LocalDate,它与Joda Time中的非常相似。

另一个简单的比较方法是基于这里的答案和我的导师指导

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());
  }
编辑: 根据@Jonathan Drapeau的说法,上述代码在某些情况下失败(我希望看到这些情况,请),据我所知,他建议如下:

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());
}
请注意,Date类已被弃用,因为它不适合国际化。Calendar类用于
boolean isSameDay = 
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)
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
    }
}
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);
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());
  }
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());
}
Date date1 = new Date();

Date date2 = new Date();

if (DateUtils.truncatedCompareTo(date1, date2, Calendar.DAY_OF_MONTH) == 0)
    // TRUE
else
    // FALSE
LocalDate date1 = LocalDate.of(2016, 2, 14);
LocalDate date2 = LocalDate.of(2015, 5, 23);
date1.isAfter(date2);
import org.apache.commons.lang3.time.DateUtils

DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)
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   
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
    }

}
public int compareTo(ArnesClass o) {
    LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
    LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
    return dateWithoutTime.compareTo(otherDateWithoutTime);
}
    LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();
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));
}
myJavaUtilDate1.toInstant()
               .atZone( ZoneId.of( "America/Montreal" ) )
               .toLocalDate()
               .isEqual (
                   myJavaUtilDate2.toInstant()
                                  .atZone( ZoneId.of( "America/Montreal" ) )
                                  .toLocalDate()
               )
Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );
LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();
Boolean sameDate = localDate1.isEqual( localDate2 );
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();
}
    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
    }
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);
@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)));
}
// 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)
}
public Boolean compareDateWithoutTime(Date d1, Date d2) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    return sdf.format(d1).equals(sdf.format(d2));
}