2009-05-11 15 views
6

Szukam klasy Java, w której można określić zestaw reguł daty, takich jak "co 3 niedziela" i "pierwsze wystąpienie poniedziałku co sekundę" miesiąc". Chcę móc uzyskać coś takiego jak nieskończony iterator (.next() zwróciłby następną datę pasującą do ustawionych reguł).Fabryka Iteratora daty Java, z regułami określającymi sposób obliczania przedziałów czasowych

Myślę, że byłbym w stanie sam ją zbudować - ale kalendarze są kłopotliwe i wydaje się, że coś podobnego powinno już istnieć. Nienawidzę bycia tym, który wymyśliłby na nowo koło crappiera.

Czy ktoś jest świadomy czegoś takiego? Patrzę na JODA, i wydaje się, że kładzie podwaliny pod niego, ale nie wydaje się, aby dać pełną funkcjonalność, którą chcę ..

Odpowiedz

7

Nie sądzę, że istnieją jakieś gotowe iteratory dla joda-time lub Javy Interfejs API kalendarza, ale w przypadku jody jest tak łatwo, że powinieneś po prostu go użyć. Na przykład po ponownym zapoznaniu się z Joda po kilku miesiącach przerwy zrobiłem to w około 10 minut:

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 czas jest niesamowite :-)

+0

Kołysałeś moje popołudnie - dziękuję kolego! –

+0

Chociaż nie jest to wcale ważne, chcę tylko powiedzieć, że jest to drugi iterator, jaki kiedykolwiek napisałem, który obsługuje remove(), zazwyczaj uważam, że jest on zbyt nieporęczny, aby go obsłużyć. – Esko

0

Możesz rzucić okiem na Quartz, który jest przeznaczony do planowania zadań.

0

tl; dr

łatwe, z java.time.

Dla 3rd czwartku:

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

kłopotliwego starych klas date-time w pakiecie z najwcześniejszych wersjach Java są już nieaktualne, wyparta przez klasy java.time.

Klasa LocalDate reprezentuje wartość tylko dla daty bez pory dnia i bez strefy czasowej.

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

Dla każdego LocalDate można dostosować do porządkowej występowania dzień-of-tydzień w tym samym miesiącu (ex: trzeci czwartek, 2 wtorek, itd.). Podaj dzień tygodnia, używając wyliczenia DayOfWeek.

Aby dokonać korekty, należy zastosować implementacje TemporalAdjuster znalezione w klasie TemporalAdjusters.

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

zastosować ten regulator do dowolnego LocalDate, tworząc kolejną LocalDate obiekt.

LocalDate thirdThursday = ld.with(thirdThursdayAdjuster) ; 

coś nieskończonego iteracyjnej z niego (.next() zwróci następny termin pasujący

Wystarczy przejść z jednego do drugiego LocalDate. Można zadzwonić LocalDate::addMonths.Lub jeśli masz do czynienia z miesiącem na raz, użyj klasy 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) ; 
} 

O java.time

Ramy java.time jest wbudowana w Java 8 i późniejszych. Te klasy zastępują kłopotliwe stare klasy dat-czasu, takie jak java.util.Date, Calendar, & SimpleDateFormat.

Projekt Joda-Time, teraz w maintenance mode, zaleca migrację do klas java.time. Aby uzyskać więcej informacji, zobacz

. I wyszukaj Stack Overflow dla wielu przykładów i objaśnień. Specyfikacja to JSR 310.

Gdzie można uzyskać lekcje java.time?

  • Java SE 8, Java SE 9, a później
    • wbudowanej.
    • Część standardowego interfejsu API języka Java z pakietem implementacji.
    • Java 9 dodaje kilka drobnych funkcji i poprawek.
  • Java SE 6 i Java SE 7
    • Znaczna część funkcjonalności java.time jest back-przeniesiony do Java 6 & 7 w ThreeTen-Backport.
  • Android
    • Późniejsze wersje Androida wdrożeń wiązce klas java.time.
    • Dla wcześniejszego systemu Android projekt ThreeTenABP dostosowuje ThreeTen-Backport (wymieniony powyżej). Zobacz How to use ThreeTenABP….

Projekt ThreeTen-Extra rozciąga java.time z dodatkowych zajęć. Ten projekt jest poligonem wskazującym na możliwe przyszłe dodatki do java.time. Możesz znaleźć tutaj kilka użytecznych klas, takich jak Interval, YearWeek, YearQuarter i more.

Powiązane problemy