在两个日期之间得到几个月,无视日子
我想统计两个日期之间的月份,并且只会比较他们的月份而忽略日期,因此2012-01-31
和2012-02-01
应该有1
个月的差异。
我用乔达时间做到这一点:
import org.joda.time.*;
PeriodType yearMonth = PeriodType.yearMonthDay().withDaysRemoved();
LocalDate dt1 = new LocalDate(2012, 1, 31);
LocalDate dt2 = new LocalDate(2012, 2, 1);
int months = new Period(dt1, dt2, yearMonth).getMonths();
System.out.println(months);
但我得到了印刷输出:
0
虽然我用.withDaysRemoved()
,但它不工作。 我滥用了吗?
java.time
Joda-Time项目现在处于维护模式。 该团队建议迁移到java.time类。
LocalDate
和Joda-Time一样, LocalDate
代表没有时间和没有时区的仅限日期的值。
LocalDate start = LocalDate.of ( 2012 , Month.JANUARY , 31 );
LocalDate stop = LocalDate.of ( 2012 , Month.MARCH , 1 );
建立一个地方来保存我们的结果。
long countMonths = 0;
YearMonth
YearMonth
类表示一年和一个月。 这是整个月考虑的渠道,而不是几天。
YearMonth ymStart = YearMonth.from ( start );
YearMonth ymStop = YearMonth.from ( stop );
此YearMonth
类具有比较方法,如isAfter
, isBefore
和equals
。
ChronoUnit
类可以计算一对Temporal
对象之间经过的月份。 YearMonth
类幸运地实现了Temporal
并与ChronoUnit
一起ChronoUnit
。
if ( ymStart.isAfter ( ymStop ) ) {
// Handle error condition. Unexpected input values.
} else if ( ymStart.equals ( ymStop ) ) {
countMonths = 0;
} else { // Else different months.
countMonths = ChronoUnit.MONTHS.between ( ymStart , ymStop );
}
转储到控制台。
System.out.println ( "start: " + start + " | stop: " + stop + " | countMonths: " + countMonths );
开始:2012-01-31 | 停止:2012-03-01 | countMonths:2
半开
以上结果基于Half-Open方法来定义一个开始包含的时间跨度,而结尾是独占的。 这种方法通常用于日期时间工作,包括整个java.time类。
所以,例如,午餐时间从午间时的第一时刻开始,一直延续到下午1点的第一时刻,但不包括在内。
另一个例子:一个星期将在星期一开始,然后跑到但不包括下一个星期一。 或者在这种情况下,从一月份开始的一对年份和上涨到但不包括三月; 他们产生了2个月的时间跨度。
我相信在整个代码中使用Half-Open方法会导致更清晰和更少的错误。 但是,如果您或您的用户要求,请在上面的结果中添加一个。
关于java.time
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧日期时间类,如java.util.Date
, .Calendar
和java.text.SimpleDateFormat
。
Joda-Time项目现在处于维护模式,建议迁移到java.time。
要了解更多信息,请参阅Oracle教程。 并搜索堆栈溢出了很多例子和解释。
大部分的java.time功能都在ThreeTen-Backport中移植到Java 6和7,并在ThreeTenABP中进一步适用于Android(请参阅如何使用...)。
ThreeTen-Extra项目将java.time扩展到其他类。 这个项目是未来可能增加java.time的一个试验场。 您可以在这里找到一些有用的课程,例如Interval
, YearWeek
, YearQuarter
等。
LocalDate
的月份算术将会并且必须始终使用月份进行计算。 您已指定期限类型以便日期不应仅用于以下事实意味着:最终结果不应显示任何日期(但LocalDate
的月份日期部分仍在内部使用)。
但是,如果您使用另一种类型,即YearMonth
,那么此类型将定义不同的月份算术:
LocalDate dt1 = new LocalDate(2012, 1, 31);
LocalDate dt2 = new LocalDate(2012, 2, 1);
YearMonth ym1 = new YearMonth(dt1.getYear(), dt1.getMonthOfYear());
YearMonth ym2 = new YearMonth(dt2.getYear(), dt2.getMonthOfYear());
PeriodType yearMonth = PeriodType.yearMonthDay();
System.out.println(new Period(ym1, ym2, yearMonth).getMonths()); // 1
System.out.println(new Period(ym1, ym2, yearMonth.withDaysRemoved()).getMonths()); // 1
在这里您还可以看到 - 在YearMonth
上下文中 - 抑制PeriodType
中的日期不相关。
上一篇: Get months between two dates ignoring the days
下一篇: How to calculate number of day name between 2 dates in javascript