Date.getYear()与Calendar.get(Calendar.YEAR)-更改实现。能行吗

时间:2018-11-08 14:04:25

标签: java date calendar localdate

我问这个问题是因为实际上我绝对没有办法测试这种情况,也许有人可以向我解释一下:)

我一直在研究由编程新手编写的一段代码。这段代码如下:

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变量中减去或减去一些东西以获得与代码中相同的结果吗?

2 个答案:

答案 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.明天回答,看看会发生什么。