使用 .compareTo 比较日期时,为什么不考虑月份?

When using .compareTo to compare dates, why doesn't it take Months into account?

我正在显示 ArrayList 中的某些日期并使用格式化程序将日期缩短为 "dd/MM" 但是当我比较日期时它在几个月内不起作用。例如17/08 是在 19/08 之前,21/08 是在 19/08 之后,但 17/09 是在 19/08 之前。我的程序实现的是显示接下来 8 天内的任何日期。

我试过使用 .compareTo 来做到这一点,它在一个月内有效,但在几个月之间不起作用。我知道它在比较字符串,我认为这是问题所在,但我不知道如何解决它

SimpleDateFormat formatter = new SimpleDateFormat("dd/MM");
Calendar cal = Calendar.getInstance();
Date comDate = new Date();
cal.add(Calendar.DATE, 8);
//this adds days to the calender
comDate = cal.getTime();
String strDate = formatter.format(comDate);
//this applies the edited calender to the date I'm comparing to

ArrayList<String> arDat = new ArrayList<String>();
arDat.add("15/08");
arDat.add("15/09");
arDat.add("30/08");

Date recDate = new Date();

for (int i=0; i < arDat.size(); i++){
    recDate = formatter.parse(arDat(i));
    String strRecDate = formatter.format(recDate);
    if (strRecDate.compareTo(strDate) < 0 {
        showToast(recDate);
    }
}

我希望它只显示 15/08,但它显示 15/08 和 15/09

您正在比较日期的字符串。日历 class 实现了 Comparable 接口。它会正确比较。

https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html

所以你的固定版本的代码:

for (int i=0; i < arDat.size(); i++){
    recDate = formatter.parse(arDat(i));
    if (recDate.compareTo(comDate) < 0 {
        showToast(recDate);
    }
}

格式化后会转换为 String。您正在格式化和比较。因此它正在进行 String 比较。因此,结果。

如果你想要预期的结果,你必须比较Date个对象。我修改了您的代码以比较 StringsDates.

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

public class CompareDates {
    public static void main(String[] args) throws Exception {
        SimpleDateFormat formatter = new SimpleDateFormat("dd/MM");
        Calendar cal = Calendar.getInstance();
        Date comDate = new Date();
        cal.add(Calendar.DATE, 8);
        //this adds days to the calender
        comDate = cal.getTime();
        //this applies the edited calender to the date I'm comparing to

        ArrayList<String> arDat = new ArrayList<String>();
        arDat.add("15/08");
        arDat.add("15/09");
        arDat.add("30/08");

        Date redDate = new Date();
        for (int i = 0; i < arDat.size(); i++) {
            Date recDate = formatter.parse(arDat.get(i));
            if (formatter.format(recDate).compareTo(formatter.format(comDate)) < 0) {
                System.out.println("String comparison result: " + recDate);
            }
            if (recDate.compareTo(formatter.parse(formatter.format(comDate))) < 0) {
                System.out.println("Date comparison result: " + recDate);
            }
        }
    }
}

这是预期的输出(与日期相比,仅打印 8 月 15 日):

String comparison result: Sat Aug 15 00:00:00 UTC 1970
Date comparison result: Sat Aug 15 00:00:00 UTC 1970
String comparison result: Tue Sep 15 00:00:00 UTC 1970

注意: 我没有直接比较 recDatecompDate 因为 compDate 是当年的(2019 ) 并且 recDate 是默认年份 (1970)。因此,我首先格式化 compDate 以去除年份、时间等,然后在比较之前再次解析为 Date

java.time.MonthDay

您可以使用现代的 java.time class 而不是使用过时的 Calendar class。如果您对日期和月份感兴趣,可以使用 MonthDay class 和它的 compareTo 方法:

MonthDay monthDay = MonthDay.of(8, 15);
MonthDay monthDay1 = MonthDay.of(9, 15);
System.out.println(monthDay.compareTo(monthDay1));

给出:

-1

您可能会发现更方便的方法 MonthDay::isBefore, isAfter, and equals

java.time classes 内置于 Java 8 及更高版本中。对于 Java 6 和 Java 7,将 ThreeTen-Backport 库添加到您的项目中。