繁体   English   中英

两个Java日期之间的区别

[英]Difference between two java Dates

我提到生产项目中的一种方法对日期的处理不正确,但是我不能仅仅替换它,因为它已经投入生产很长时间了。 我创建了一个新方法,该方法可以正确运行,但是我不知道为什么第一种方法会出错。

旧方法(效果不佳):

public static Integer getNumberOfDays(Date startDate, Date endDate) {
    TimeZone.setDefault((TimeZone.getTimeZone("Europe/Moscow")));

    startDate.setHours(00);
    startDate.setMinutes(00);
    startDate.setSeconds(00);

    endDate.setHours(23);
    endDate.setMinutes(59);
    endDate.setSeconds(59);

    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(startDate);

    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(endDate);

    Calendar date = (Calendar) cal1.clone();
    int daysBetween = 0;
    while (date.before(cal2)){
        date.add(Calendar.DAY_OF_MONTH, 1);
        daysBetween++;
    }
    return daysBetween;
}

新方法:

public static Integer getNumberOfDaysSecondVersion(Date startDate, Date endDate) {
    long difference = startDate.getTime() - endDate.getTime();
    float daysBetween = (difference / (1000*60*60*24));
    return (int) daysBetween > 0 ? (int) daysBetween : 0;
}

这是我两者的称呼:

DateFormat formated = new SimpleDateFormat("yyyy-MM-dd");

    System.out.println(Calculation.getNumberOfDays(
            formated.parse("2018-06-14"),
            formated.parse("2018-06-06")
    ));

    System.out.println(Calculation.getNumberOfDaysSecondVersion(
            format.parse("2018-06-14"),
            format.parse("2018-06-06"))
    );

输出:

0
8

请帮忙。

您的旧方法是正确的方法。 当开始日期晚于结束日期时,它返回0。在您的呼叫中就是这种情况。

您的新方法从开始日期中减去结束日期,这是错误的,应该相反。 我还怀疑它会给夏令时(DST)前后的过渡带来惊喜。 尽管莫斯科目前不使用夏季时间,但从历史上看,至少一直到2010年为止,如果政界人士决定这样做,莫斯科可能会再次使用夏季时间。

就是说,您应该尝试避免使用旧的和过时的日期和时间类DateFormatSimpleDateFormatCalendarDateTimeZone 今天,我们在现代Java日期和时间API java.time有了更好的java.time 当然,在旧版代码中,您具有老式的Date对象。 编写新方法时,建议您将其转换为现代的LocalDate并使用ChronoUnit.DAYS.between()

ChronoUnit.DAYS.between(
    LocalDate.parse( "2018-06-14" ) ,
    LocalDate.parse( "2018-06-06" ) 
)

-8

请注意,当旧方法设置默认时区时,它将影响在JVM中运行的所有程序,并且可能会对程序的其他部分和其他程序产生令人讨厌的惊喜。

可能是因为startDate和endDate的时区不受设置默认时区的影响,所以当您基于它们设置日历时间(以莫斯科时间为单位)时,您正在转换时区,可能将00:00:00转换为前一天21 :00:00之类的。

编辑

看到您的输出,这很明显...您传递的是开始日期,而不是结束日期。 原始方法使用只能累加的循环,而新方法采用差的绝对值。

对于两个版本,您使用了非常不同的算法。

旧版本会在开始日期之前增加几天,直到结束日期之后。

新版本从开始日期减去结束日期,然后将其除以一天中存在的毫秒数。

这意味着要使用第一个版本,开始日期必须早于结束日期,而要使用第二个版本,开始日期必须晚于结束日期。 您为第一个版本提供的参数的开始日期在结束日期之后,因此返回0。

要解决此问题,您可以反转两个参数:

System.out.println(getNumberOfDays(
        formated.parse("2018-06-06"),
        formated.parse("2018-06-14")
));

或者,在计算两者之间的差额之前,先检查哪个日期先到。

顺便说一句,您的第一个版本似乎比第二个版本输出更多。 您似乎想要8天的结果。 这意味着您的第一个版本存在1比1错误。 您可以通过从计数结果中减去1来解决此问题。

请记住,只要有可能,就始终使用java.time

暂无
暂无

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

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