Фабрика итераторов дат Java с правилами, определяющими, как вычислять интервалы

StackOverflow https://stackoverflow.com/questions/847520

  •  21-08-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

Я не думаю, что есть какие-либо готовые итераторы для joda-time или Java Calendar API, если на то пошло, однако с joda это настолько просто, что вы должны просто использовать это.Например, после повторного ознакомления с 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();
    }
}

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

Другие советы

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

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

вр; доктор

Легко, с 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 class представляет значение только даты без времени суток и часового пояса.

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

Для любого LocalDate, вы можете настроить порядковый номер дня недели в пределах одного месяца (например:третий четверг, 2-й вторник и т. д.).Укажите день недели, используя DayOfWeek перечисление.

Для регулировки используйте 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 Framework встроен в Java 8 и более поздних версий.Эти занятия заменяют надоедливые старые наследие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

А Джода-Время проект, сейчас в Режим обслуживания, советует перейти на java.time занятия.

Чтобы узнать больше, см. Учебное пособие по Oracle.И найдите Stack Overflow для множества примеров и объяснений.Спецификация ДжСР 310.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top