Java date iterator factory,其中的规则指定了如何计算间隔

我正在寻找一个Java类,我可以在其中指定一组日期规则,例如“每隔3个星期日”和“每隔一个月第一次出现星期一”。 我希望能够从中获得类似无限迭代器的东西(.next()将返回与规则集匹配的下一个日期)。

我想我自己可以自己构建它 – 但是日历很麻烦,而且感觉类似的东西已经存在了。 我讨厌成为重塑一个更快的轮子的人。

有人知道这样的事吗? 我一直在看JODA,它似乎为它奠定了基础,但似乎没有提供我想要的全部function..

我认为没有为joda-time或Java Calendar API做任何容易的迭代器,但是对于joda而言,它应该很容易实现。 例如,在几个月的停顿后重新熟悉joda之后,我在大约10分钟内做到了这一点:

public class InstantIterator implements Iterator, Iterable { private Instant current; private final Instant original; private Duration skip; private List skipThese; public InstantIterator(Instant startFrom, Duration skip) { this.current = original = startFrom; this.skip = skip; skipThese = new Vector(); } public boolean hasNext() { return true; } public Instant next() { Instant currentNext = current.toInstant(); current = current.plus(skip); while (skipThese.contains(currentNext)) { currentNext = current.toInstant(); current = current.plus(skip); } return currentNext; } public void remove() { skipThese.add(current.toInstant()); } public Iterator iterator() { return this; } public void rewind() { current = original.toInstant(); } public void resetRemoved() { skipThese.clear(); } public void resetIterator() { rewind(); resetRemoved(); } } 

Joda时间很棒:-)

我的公司有一些非常像你想要的东西,但它适用于.NET,所以它可能对你没有任何好处。

您可以查看专为作业调度而设计的Quartz 。

TL;博士

简单,使用java.time

第三个星期四:

 LocalDate.now().with( // Get today's date, then adjust. TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.THURSDAY ) // Define adjuster to move to third Thursday of same month. ) // Instantiates another `LocalDate` object (java.time uses immutable objects). 

java.time

与最早版本的Java捆绑在一起的麻烦的旧日期时间类现在已经过时,取而代之的是java.time类。

LocalDate类表示没有时间且没有时区的仅日期值。

 LocalDate ld = LocalDate.of( 2018 , Month.FEBRUARY , 17 ) ; 

对于任何LocalDate ,您可以调整到同一个月内某一天的序数事件(例如:第三个星期四,第二个星期二等)。 使用DayOfWeek枚举指定星期几。

要进行调整,请使用TemporalAdjusters类中的TemporalAdjuster实现。

 TemporalAdjuster thirdThursdayAdjuster = TemporalAdjusters.dayOfWeekInMonth​( 3 , DayOfWeek.THURSDAY ) ; // Third-Thursday. 

将该调整器应用于任何LocalDate ,生成另一个LocalDate对象。

 LocalDate thirdThursday = ld.with( thirdThursdayAdjuster ) ; 

类似于无限迭代器的东西(.next()将返回下一个日期匹配

只需从一个LocalDate移动到另一个LocalDate 。 你可以调用LocalDate::addMonths 。 或者,如果一次处理一个月,请使用YearMonth类。

 TemporalAdjuster thirdThursdayAdjuster = TemporalAdjusters.dayOfWeekInMonth​( 3 , DayOfWeek.THURSDAY ) ; // Third-Thursday. List dozenThirdThursdays = new ArrayList<>( 12 ) ; YearMonth start = YearMonth.of( 2018 , Month.MARCH ) ; for( int i = 1 ; i <= 12 ; i ++ ) { YearMonth ym = start.plusMonths( i ) ; LocalDate firstOfMonth = ym.atDay( 1 ) ; LocalDate thirdThursday = firstOfMonth.with( thirdThursdayAdjuster ) ; dozenThirdThursdays.add( thirdThursday ) ; } 

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。

从哪里获取java.time类?

  • Java SE 8Java SE 9及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
  • Android的
    • 更高版本的Android捆绑java.time类的实现。
    • 对于早期的Android, ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ....

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。