6 Stimmen

Java-Datums-Iterator-Fabrik mit Regeln, die angeben, wie die Intervalle zu berechnen sind

Ich bin auf der Suche nach einer Java-Klasse, in der ich eine Reihe von Datumsregeln angeben kann, wie z. B. "jeden 3. Sonntag" und "das erste Auftreten eines Montags jeden zweiten Monat". Ich möchte in der Lage sein, so etwas wie einen unendlichen Iterator zu erhalten (.next() würde das nächste Datum zurückgeben, das den festgelegten Regeln entspricht).

Ich glaube, ich könnte es selbst bauen - aber Kalender sind mühsam, und ich habe das Gefühl, dass es so etwas schon geben sollte. Ich hasse es, derjenige zu sein, der das Rad neu erfindet.

Ist jemandem etwas Derartiges bekannt? Ich habe mir JODA angesehen, und es scheint die Grundlagen dafür zu schaffen, aber es scheint nicht die volle Funktionalität zu bieten, die ich möchte.

7voto

Esko Punkte 28242

Ich glaube nicht, dass es irgendwelche fertigen Iteratoren für Joda-Zeit oder Java Kalender-API für diese Angelegenheit, aber mit Joda ist es so einfach, dass Sie einfach mit ihm gehen sollte. Zum Beispiel, nachdem ich mich nach ein paar Monaten Pause wieder mit Joda vertraut gemacht habe, habe ich das hier in etwa 10 Minuten gemacht:

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();
    }
}

Joda Time ist großartig :-)

0voto

BCS Punkte 71108

Mein Unternehmen hat etwas sehr ähnliches wie Sie wollen aber es ist für .NET, also wird es Ihnen wahrscheinlich nichts nützen.

0voto

Peter Lawrey Punkte 511323

Schauen Sie doch mal unter Quarz das für die Auftragsplanung vorgesehen ist.

0voto

Basil Bourque Punkte 256611

Tl;dr

Einfach, mit java.time .

Für den 3. Donnerstag:

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

Die lästigen alten Date-Time-Klassen, die mit den frühesten Versionen von Java mitgeliefert wurden, sind nun veraltet und durch die java.time-Klassen ersetzt worden.

El LocalDate stellt einen reinen Datumswert ohne Uhrzeit und ohne Zeitzone dar.

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

Für jede LocalDate können Sie das ordinale Auftreten eines Wochentags innerhalb desselben Monats einstellen (z. B. dritter Donnerstag, zweiter Dienstag usw.). Geben Sie den Wochentag an mit DayOfWeek enum.

Verwenden Sie für die Einstellung einen TemporalAdjuster Implementierungen, die in der TemporalAdjusters classe.

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

Wenden Sie diesen Einsteller auf jede LocalDate und erzeugt eine weitere LocalDate Objekt.

LocalDate thirdThursday = ld.with( thirdThursdayAdjuster ) ;

so etwas wie einen unendlichen Iterator daraus machen (.next() würde das nächste passende Datum zurückgeben

Bewegen Sie sich einfach von einem LocalDate zum anderen. Sie könnten anrufen LocalDate::addMonths . Oder, wenn Sie einen Monat auf einmal behandeln, verwenden Sie die YearMonth classe.

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 ) ;
}

Über java.time

El java.time Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Erbe Datum-Zeit-Klassen wie java.util.Date , Calendar , & SimpleDateFormat .

El Joda-Time Projekt, jetzt in Wartungsmodus rät zur Migration auf den java.time Klassen.

Weitere Informationen finden Sie in der Oracle-Tutorial . Und suchen Sie auf Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR 310 .

Wo erhält man die java.time-Klassen?

  • Java SE 8 , Java SE 9 und später
    • Eingebaut.
    • Teil der Standard-Java-API mit einer gebündelten Implementierung.
    • Java 9 fügt einige kleinere Funktionen und Korrekturen hinzu.
  • Java SE 6 et Java SE 7
    • Ein Großteil der java.time-Funktionalität wurde in Java 6 und 7 zurückportiert in DreiZehn-Backport .
  • Android
    • Spätere Versionen von Android bündeln Implementierungen der java.time-Klassen.
    • Bei früheren Android-Versionen ist die DreiZehnABP Projekt passt sich an DreiZehn-Backport (siehe oben). Siehe Wie benutzt man ThreeTenABP .

El DreiZehn-Extra Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt dient als Versuchsfeld für mögliche zukünftige Erweiterungen von java.time. Sie finden hier vielleicht einige nützliche Klassen wie Interval , YearWeek , YearQuarter et mehr .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X