当大于等于而不是严格大于时,将日历 class 中的 after 方法修改为 return true

modifying the after method in calender class to return true when greater than equal to instead of strictly greater

import java.util.Calendar;
import java.util.Date;

public class exercise4 {
    public static void main (String[] args) throws InterruptedException {
    Calendar cal1 = new CalendarSubclass();
    cal1.setTime(new Date());
    Thread.sleep(1000);
    Calendar cal2 = new CalendarSubclass();
    cal2.setTime(new Date());
    System.out.println(cal2.after(cal1));
    System.out.println(cal1.after(cal2));
    System.out.println(cal1.after(cal1));
    System.out.println(cal2.after(cal2));
    }
}

class CalendarSubclass extends Calendar {
    @Override
    public boolean after(Object when) {
        if (when instanceof Calendar && super.compareTo((Calendar) when) == 0) {
        //if (when instanceof Calendar && ((Calendar) when).toString().equals(this.toString())) {
        //if (when instanceof Calendar && equals((Calendar) when)) {        
        //          System.out.println("lala");
            return true;
        }
        return super.after(when);
    }
@Override
public int compareTo(Calendar anotherCalendar) {
    return compareDays(this.getFirstDayOfWeek(), anotherCalendar.getFirstDayOfWeek());
}

private int compareDays(int currentFirstDayOfWeek, int anotherFirstDayOfWeek) {
    return (currentFirstDayOfWeek > anotherFirstDayOfWeek) ? 1
            : (currentFirstDayOfWeek == anotherFirstDayOfWeek) ? 0 : -1;
}

}

输出是:

false, false, true, true 

但应该是

true, false, true, true 

因为我已经使用 CalenderSubclass 覆盖了 after 方法。

编辑:当我删除 compareTo 和 compareDays 方法时它起作用了,但我只允许修改 after 方法!

通过你的更新,我可以看到导致问题的原因:

覆盖的 compareTo(Calendar anotherCalendar)Calendar.compareTo 方法的无效实现。 Calendar.compareTo() 方法的文档指出:

Compares the time values [..] represented by two Calendar objects.

但是覆盖方法显然做了其他事情(它比较 "firstDayOfWeek" 字段,这只对为不同语言环境配置的 Calendar 实例有意义。)

如果可以:运行 远离并寻求躲避这种破旧代码!


如果不能:重新实现原始日历 compareTo 方法的作用:

@Override
public boolean after(Object when) {
    if (when instanceof Calendar) {
        Calendar other = (Calendar) when;
        return getTimeInMillis() >= other.getTimeInMillis();
    }
    return super.after(when);
}

三点建议:

  1. 使用来自 java.time 的 classes、现代 Java 日期和时间 API,以及那些。不要使用 Calendar。 class 设计不佳且早已过时。
  2. 为此创建一个实用方法而不是使用 subclassing。
  3. 为您的实用程序方法起一个明显区别于 Calendarafter 方法的名称。称它为 after 会导致很多程序员认为它与现有的 after 方法具有相同的语义,意思是严格之后。你可能会很困惑。

例如:

public static boolean isBeforeOrOn(Instant i1, Instant i2) {
    return ! i1.isAfter(i2);
}

public static boolean isOnOrAfter(Instant i1, Instant i2) {
    return ! i1.isBefore(i2);
}

让我们试试看:

    Instant i1 = Instant.now();
    Instant i2 = i1.plusSeconds(1);
    System.out.println("i2 is on or after i1? " + isOnOrAfter(i2, i1));
    System.out.println("i1 is on or after i2? " + isOnOrAfter(i1, i2));
    System.out.println("i1 is on or after i1? " + isOnOrAfter(i1, i1));
    System.out.println("i1 is before or on i2? " + isBeforeOrOn(i1, i2));
    System.out.println("i2 is before or on i2? " + isBeforeOrOn(i2, i2));

输出:

i2 is on or after i1? true
i1 is on or after i2? false
i1 is on or after i1? true
i1 is before or on i2? true
i2 is before or on i2? true

Link: Oracle tutorial: Date Time 解释如何使用 java.time.