Фабрика итераторов даты Java, с правилами, определяющими, как вычислять интервалы - PullRequest
6 голосов
/ 11 мая 2009

Я ищу класс Java, в котором я могу указать набор правил дат, таких как «каждое 3-е воскресенье» и «первое появление понедельника каждый второй месяц». Я хочу иметь возможность получить что-то вроде бесконечного итератора из этого (.next () вернет следующую дату, соответствующую установленным правилам).

Я думаю, что смогу создать его сам, но календари - это хлопот, и кажется, что нечто подобное уже должно существовать. Я ненавижу быть тем, кто изобретает более крутое колесо.

Кто-нибудь знает что-то подобное? Я смотрел на JODA, и он, кажется, закладывает основу для этого, но, похоже, не дает полной функциональности, которую я хочу ..

Ответы [ 4 ]

7 голосов
/ 11 мая 2009

Я не думаю, что есть какие-либо готовые итераторы для joda-time или Java Calendar API в этом отношении, однако с joda это так просто, что вы должны просто пойти на это. Например, после повторного знакомства с Йодой после нескольких месяцев паузы я сделал это примерно через 10 минут:

public class InstantIterator implements Iterator<Instant>,
                                        Iterable<Instant> {

    private Instant current;
    private final Instant original;
    private Duration skip;
    private List<Instant> skipThese;

    public InstantIterator(Instant startFrom, Duration skip) {
        this.current = original = startFrom;
        this.skip = skip;
        skipThese = new Vector<Instant>();
    }

    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<Instant> iterator() {
        return this;
    }

    public void rewind() {
        current = original.toInstant();
    }

    public void resetRemoved() {
        skipThese.clear();
    }

    public void resetIterator() {
        rewind();
        resetRemoved();
    }
}

Джода Время потрясающее: -)

0 голосов
/ 26 января 2018

ТЛ; др

Легко, с java.time .

за 3-й четверг:

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 вы можете настроить порядковое вхождение дня недели в том же месяце (например: третий четверг, 2-й вторник и т. Д.). Укажите день недели, используя DayOfWeek enum.

Чтобы выполнить корректировку, используйте TemporalAdjuster реализаций, найденных в TemporalAdjusters классе.

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

Примените этот регулятор к любому LocalDate, создав другой объект LocalDate.

LocalDate thirdThursday = ld.with( thirdThursdayAdjuster ) ;

что-то вроде бесконечного итератора из него (.next () вернет следующую дату, соответствующую

Просто переходите от одного LocalDate к другому. Вы можете позвонить LocalDate::addMonths. Или, если вы имеете дело с месяцем за раз, используйте класс YearMonth.

TemporalAdjuster thirdThursdayAdjuster = TemporalAdjusters.dayOfWeekInMonth​( 3 , DayOfWeek.THURSDAY ) ;  // Third-Thursday. 
List<LocalDate> 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.Date, Calendar и & SimpleDateFormat.

Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Где получить классы java.time?

  • Java SE 8 , Java SE 9 и выше
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android проект ThreeTenABP адаптируется ThreeTen-Backport (упоминалось выше). См. Как использовать ThreeTenABP… .

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и more .

0 голосов
/ 12 мая 2009

Вы можете взглянуть на Кварц , который предназначен для планирования работы.

0 голосов
/ 11 мая 2009

В моей компании есть что-то очень похожее на то, что вы хотите , но это для .NET, поэтому, вероятно, вам это не поможет.

...