使用日历比较 Java 7 中的日期

Comparing Dates in Java 7 using Calendar

我正在比较治疗的开始日期和结束日期,以检查治疗是否持续超过 6 个月。如果这段时间不包括二月,一切都很好,但如果我将 1 月 1 日与 6 月 30 日进行比较,它会抛出我的异常。为了比较这两个时间段,我将 6 个月添加到开始日期并将结果与​​结束日期进行比较,如下所示:

Date start = new Date(2017,1,1);
Date end = new Date(2017,6,30);

Calendar startOfTreatment = new Calendar.getInstance();
startOfTreatment.setTime(start);

Calendar endOfTreatment = new Calendar.getInstance();
endOfTreatment.setTime(end);

startOfTreatment.add(Calendar.MONTH, 6);
if (startOfTreatment.compareTo(endOfTreatment) > 0) {
    throw new InfinishedTreatmentException(startOfTreatment,endOfTreatment);
}

我该如何解决这个问题?

Date 构造器(比如您正在使用的构造器:new Date(2017,1,1))不仅 已弃用 (因此您应该避免使用它们)而且误导性,因为年份的索引为 1900(因此 2017 年变为 3917),月份的索引为零(值在零(一月)到 11(十二月)的范围内)。所以这并不像你想象的那样:

Date start = new Date(2017, 1, 1); // February 1st 3917
Date end = new Date(2017, 6, 30); // July 30th 3917

start 上加上 6 个月就变成了 8 月 1 日st,在 [=16= 之后].

要创建 1 月 1 日st 和 6 月 30 日th,您必须使用 month - 1 并且必须使用 2017 年使用 117 (2017 - 1900):

Date start = new Date(117, 0, 1); // January 1st 2017
Date end = new Date(117, 5, 30); // June 30th 2017

尽管如此,start加上 6 个月将是 7 月 1 日st,这仍然是在 [=16= 之后](所以你的代码会抛出异常)。


旧的 类(DateCalendarSimpleDateFormat)有 lots of problems and design issues,它们正在被新的 APIs.

Java <= 7 中,您可以使用 ThreeTen Backport,这是 Java 8 的新 date/time 的一个很好的向后移植] 类.

这个新的 API 有 lots of new date and time types 来处理不同的情况。因为我们只处理日期 (day/month/year),所以我们可以使用 org.threeten.bp.LocalDate:

LocalDate start = LocalDate.of(2017, 1, 1); // January 1st 2017
LocalDate end = LocalDate.of(2017, 6, 30); // June 30th 2017

// 6 months after start
LocalDate sixMonthsLater = start.plusMonths(6);
if (sixMonthsLater.isAfter(end)) {
    // throw exception
}