为什么 GregorianCalendar 方法 add() 不起作用?

Why GregorianCalendar method add() does not work?

我创建了一个 class 代表图书馆系统的可能用户。在创建此实例时,我需要设置两个字段:signingUpDateexpirationDate,它们都是公历。

signingUpDate是创建时刻的日期,expirationDatesigningUpDate+5年。

public class User {

    private GregorianCalendar signingUpDate;
    private GregorianCalendar expirationDate;

    public User(){
        setSigningUpDate;
        setExpirationDate;
    }

    private void setExpirationDate() {
        this.expirationDate = new GregorianCalendar();
        expirationDate.add(GregorianCalendar.YEAR, 5);
    }

    private void setSigningUpDate() {
        this.signingUpDate=new GregorianCalendar();
    }

当我使用add()方法时,expirationDate没有改变。我尝试调试,发现字段 areFieldsSet 变为假。但是我不明白那个字段的含义。 有人可以帮助我吗?

GregorianCalendar的一个bug(?),你可以调用getTime到'refresh'它加上5年:

signingUpDate.add(Calendar.YEAR, 5);
signingUpDate.getTime();

另一个解决方案,使用 java.time 包代替,例如 java.time.LocalDate.

java.time

public class User {

    private static final ZoneId ZONE = ZoneId.of("America/Kentucky/Monticello");
    private static final Period VALIDITY = Period.ofYears(5);

    private LocalDate signingUpDate;
    private LocalDate expirationDate;

    public User() {
        setSigningUpDate();
        setExpirationDate();
    }

    private void setSigningUpDate() {
        this.signingUpDate = LocalDate.now(ZONE);
    }

    private void setExpirationDate() {
        this.expirationDate = signingUpDate.plus(VALIDITY);
    }

    @Override
    public String toString() {
        return "Signed up " + signingUpDate + " expires " + expirationDate; 
    }
}

java.time,现代 Java 日期和时间 API,没有 GregorianCalendar 和其他日期和时间 classes 的令人不快的惊喜来自 Java 1.0 和 1.1。所以好的解决方案是跳过旧的 classes 并使用现代的。

你的代码出了什么问题?

您的代码没有任何错误。我也不太确定是什么让您感到困惑,但是 GregorianCalendar class 肯定令人困惑,所以我也不感到惊讶。也许您查看了调试器中的 GregorianCalendar 对象,发现年份没有变化,而 areFieldsSet 已更改为 false。他们试图记录这种令人困惑的行为,但由于它非常不自然并且与您预期的不同,因此文档也很难阅读和理解。

Link

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