我问这个问题是因为实际上我绝对没有办法测试这种情况,也许有人可以向我解释一下:)
我一直在研究由编程新手编写的一段代码。这段代码如下:
List<Date> dateList = infoFacade.getDateFrom(documentId);
for(Date from : dateList) {
LocalDate now1 = LocalDate.now();
int year = now1.getYear();
int previousyear = now1.getYear()-1;
int yearfrom = from.getYear()+1900;
if((yearfrom == year )|| (yearfrom == previousyear )){
idoc.setBauinfoArzvon(from);
}
}
我已经对其进行了一些重写,因此我们停止使用不推荐使用的方法。看起来像这样:
for (Date from : infoFacade.getDateFrom(documentId))
{
cal.setTime(from);
int yearfrom = cal.get(Calendar.YEAR);
if ((yearfrom == LocalDate.now().getYear())
|| (yearfrom == (LocalDate.now().getYear() - 1)))
{
idoc.setDateFrom(from);
}
}
我担心所有+1900或-1900的问题。在重构之前,我应该从yearfrom
变量中减去或减去一些东西以获得与代码中相同的结果吗?
答案 0 :(得分:2)
假设您无法更改infoFacade.getDateFrom()
的返回类型,我的建议是:
ZoneId zone = ZoneId.systemDefault();
LocalDate now1 = LocalDate.now(zone);
int year = now1.getYear();
int previousYear = year - 1;
List<Date> dateList = infoFacade.getDateFrom(documentId);
for (Date from : dateList) {
int yearfrom = from.toInstant().atZone(zone).getYear();
if (yearfrom == year || yearfrom == previousYear) {
idoc.setBauinfoArzvon(from);
}
}
两个版本的代码都隐式依赖JVM的时区(这是脆弱的)。我已经明确表明了这种依赖性。我只读取默认时区和当前日期一次,以确保结果一致。通过先将Date
转换为Instant
然后转换为ZonedDateTime
,我避免了 both 和过时的方法 过时的Calendar
类。以及有关是否增加或减少1900的任何考虑,这使代码更清晰,读者的疑问也更少。
也可以更直接地回答您的问题:不,在您重写的代码版本中,您不应加或减1900(或任何其他数字)。该代码确实给出了相同的结果。这是因为Date
使用的是“基于1900的年份”(例如,以2018年为118),而过时的Calendar
类也使用与人类相同的年份来编号。我担心的是不同的:如果在代码运行时默认时区发生了变化,或者新年过了(不太可能,但有可能),LocalDate.now()
不会每次都给出相同的结果,因此结果将不一致。可以随时从程序的另一部分或在同一JVM中运行的另一个程序中更改JVM的默认时区。
答案 1 :(得分:1)
我写了一个简单的测试:
public static void main(String[] args) {
Date date = new GregorianCalendar().getTime();
Calendar cal = new GregorianCalendar();
cal.setTime(date);
System.out.println(cal.get(Calendar.YEAR));
System.out.println((LocalDate.now().getYear() - 1));
System.out.println(LocalDate.now().getYear());
LocalDate now1 = LocalDate.now();
int year = now1.getYear();
int previousyear = now1.getYear()-1;
int yearfrom = date.getYear()+1900;
System.out.println(year);
System.out.println(previousyear);
System.out.println(yearfrom);
}
此测试的输出为:
2018
2017
2018
2018
2017
2018
所以两个代码示例给出的结果相同。
但是我会尝试使用@Ole V.V.明天回答,看看会发生什么。