如何在 Joda-Time 中总结岁月

How to Round Up Years in Joda-Time

Joda-Time 中是否有现有的方法来对年份进行四舍五入?

假设您有一个 DateTime startDate = 10-18-2016 和一个 DateTime endDate = 12-18-2017。我希望将其舍入到 2 年。

目前,当我这样做时:

Years yearsBetween = Years.yearsBetween(startDate, endDate);

我得到 yearsBetween = 1。是否有使用 Joda Time 解决此问题的简单方法,或者我是否需要编写自定义方法来处理此问题?

tl;博士

  • 将开始日期移至年初。
  • 将结束日期移至其年的第一天。

半开

Joda-Time 使用半开方法处理时间跨度,其中开始是 包含 ,结束是 不包含 。因此,一年从相关年份的 1 月 1 日开始,一直到但不包括下一年的 1 月 1 日。

因此您希望 2016-2017 年的日期为两年,将开始日期移至该年的第一天,将结束日期移至其下一个[=116]的第一年=]年.

我们转换为 LocalDate,因为我们不关心这种年计算的时间。

LocalDate start = startDate.toLocalDate().withDayOfMonth( 1 ).withMonthOfYear( 1 );  // Move to first of same year.
LocalDate stop = endDate.toLocalDate().withDayOfMonth( 1 ).withMonthOfYear( 1 ).plusYears(1);  // Move to first of *following* year.

然后用 Years 执行相同的计算。

Years yearsBetween = Years.yearsBetween( start , stop );  // Half-Open, beginning is inclusive while ending is exclusive.
int years = yearsBetween.getYears();  // Plain integer.

2016 年(移至 2016-01-01)和 2017 年(移至 2018-01-01)任何日期的 2 结果。


java.time

仅供参考,Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.

这项工作在java.time中稍微简单一些。 TemporalAdjuster interface provides for classes to manipulate date-time values. The TemporalAdjusters class(注意复数 s)提供了几种实现。这些提供了获得今年的第一名和明年的第一名。

这里的Zdt,指的是您手头可能有的ZonedDateTime件物品。此 class 表示特定时区 (ZoneId) 时间轴上的一个时刻,分辨率为纳秒。我们从 ZonedDateTime 对象转换为 LocalDate,然后应用一对 TemporalAdjuster 对象移动到今年的第一年和下一年。

LocalDate start = yourStartingZdt.toLocalDate().with( TemporalAdjusters.firstDayOfYear() );
LocalDate stop = yourEndingZdt.toLocalDate().with( TemporalAdjusters.firstDayOfNextYear() );

java.time classes 不包括 Joda-Time Years class. If desired, you can add the ThreeTen-Extra project to your app to extend java.time with additional classes that include a Years class.

的等价物

或者,我们可以通过 Period class 获取年数。

像 Joda-Time 一样,java.time classes 包括 Period 使用半开方法处理时间跨度。我建议你自己在所有日期时间工作中始终如一地使用半开,因为它会使你的代码更简单,更不容易出错。

Period p = Period.between( start , stop );
int years = p.getYears();

2016 年(移至 2016-01-01)和 2017 年(移至 2018-01-01)任何日期的 2 结果。

关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.

Joda-Time project, now in maintenance mode,建议迁移到java.time。

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

从哪里获得java.time classes?

  • Java SE 8 and SE 9 及更高版本
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and SE 7
  • Android
    • ThreeTenABP项目专门为Android改编了ThreeTen-Backport(上面提到的)。
    • 参见

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

这在上面的评论之一中提到并且对我有用:

LocalDate startLocalDate = new LocalDate(startDate)
LocalDate endLocalDate = new LocalDate(endDate).plusYears(1).minusDays(1)

int yearsBetween = Years.yearsBetween(startLocalDate, endLocalDate).Years