我创建了一个类,它表示库系统的可能用户。在创建这个实例的时候,我需要设置两个字段:signingUpDate
和expirationDate
,它们都是公历。
signingUpDate
是创建时的日期,expirationDate
是signingUpDate
+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
变为false。但我不明白那个领域的意义。有人能帮我吗?
GregorianCalendar
的一个bug(?(,您可以在添加5年后调用getTime
来"刷新"它:
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日期和时间API java.time没有GregorianCalendar
和java 1.0和1.1中的其他日期和时间类的令人不快的惊喜。因此,好的解决方案是跳过旧类,转而使用现代类。
你的代码出了什么问题
您的代码中没有任何错误。我也不太确定是什么让你困惑,但GregorianCalendar
类肯定是令人困惑的,所以我也不感到惊讶。也许您查看了调试器中的GregorianCalendar
对象内部,发现年份没有变化,areFieldsSet
被更改为false。他们试图记录这种令人困惑的行为,但由于它非常不自然,与你预期的不同,因此文档也很难阅读和理解。
链接
Oracle教程:日期-时间,解释如何使用java.time
。