简体   繁体   English

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

[英]Date.getYear() vs. Calendar.get(Calendar.YEAR) - change of implementation. Will it work?

I am asking this question cause actually I have absolutely no way to test this case, and maybe someone could explain it to me :) 我问这个问题是因为实际上我绝对没有办法测试这种情况,也许有人可以向我解释一下:)

I have been working on a piece of code that was written by a person who is very new to programming. 我一直在研究由编程新手编写的一段代码。 This code looks like this: 这段代码如下所示:

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); 
        }
}

I have rewritten it a little bit, so we stop using a deprecated method. 我已经对其进行了一些重写,因此我们不再使用不推荐使用的方法。 It looks like this: 看起来像这样:

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);
    }
}

I am worried about all that +1900 or -1900 thing. 我担心所有+1900或-1900的问题。 Should I add or substract something from the yearfrom variable to get the same results as in the code before refactoring? 在重构之前,我是否应该从yearfrom变量中添加或减去某些内容,以获得与代码中相同的结果?

Assuming you cannot change the return type of infoFacade.getDateFrom() my suggestion would be: 假设您无法更改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);
        }
    }

Both versions of your code implicitly rely on the JVM's time zone (which is fragile). 这两个版本的代码都隐式依赖JVM的时区(这是易碎的)。 I have made this dependency explicit. 我已经明确表明了这种依赖性。 I am reading the default time zone and the current date only once to ensure consistent results. 我只读取默认时区和当前日期一次,以确保结果一致。 And by converting the Date first to an Instant and then to ZonedDateTime I am avoiding both the deprecated method and the old and outdated Calendar class. 通过将Date首先转换为Instant ,然后转换为ZonedDateTime我避免了既不推荐使用的方法 ZonedDateTime使用旧的和过时的Calendar类。 And any considerations about whether to add or subtract 1900 or not, which gives clearer code and fewer doubts on the part of the reader. 以及有关是否增加或减少1900的任何考虑,这使代码更清晰,读者的疑虑也更少。

To answer your question more directly too: No, in your rewritten version of the code you should neither add nor subtract 1900 (or any other number). 要更直接地回答您的问题:否,在代码的重写版本中,您既不应添加或减去1900(或任何其他数字)。 The code does give the same result. 该代码确实给出了相同的结果。 This is because Date uses a “1900-based year” (where 2018 is given as 118, for example), while the also outdated Calendar class numbers the years the same way humans do. 这是因为Date使用“基于1900的年份”(例如,以2018为118),而同样过时的Calendar类对年份的编号方式也与人类相同。 My worry is different: If either the default time zone changes while the code is running or (unlikely, but possible) New Year passes, LocalDate.now() will not give the same result each time, so your results will be inconsistent. 我担心的是不同的:如果在代码运行时默认时区发生了变化,或者(过年但不太可能,但可能)新年过后, LocalDate.now()不会每次都给出相同的结果,因此您的结果将不一致。 The JVM's default time zone can be changed at any time from another part of your program or another program running in the same JVM. 可以随时从程序的另一部分或在同一JVM中运行的另一个程序更改JVM的默认时区。

I have written a simple test: 我写了一个简单的测试:

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);
    }

The output of this test is: 该测试的输出为:

2018
2017
2018
2018
2017
2018

So both code samples are giving the same result. 因此,两个代码示例都给出相同的结果。

BUT i will try to use the @Ole VV answer tomorrow to see what will happen. 但是我明天将尝试使用@Ole VV答案以查看会发生什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM