使用 .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
个对象。我修改了您的代码以比较 Strings
和 Dates
.
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
注意: 我没有直接比较 recDate
和 compDate
因为 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 库添加到您的项目中。
我正在显示 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
个对象。我修改了您的代码以比较 Strings
和 Dates
.
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
注意: 我没有直接比较 recDate
和 compDate
因为 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 库添加到您的项目中。