2009-05-11 7 views
6

Cerco una classe Java dove posso specificare un insieme di regole di data, come "ogni 3 ° domenica" e "la prima occorrenza di un lunedi ogni secondo mese". Voglio essere in grado di ottenere qualcosa di simile a un iteratore infinita fuori di esso (.Next() restituirà la prossima data corrispondere le regole stabilite).Java fabbrica data iteratore, con regole che specifica come calcolare gli intervalli

credo che sarei in grado di costruire da solo - ma i calendari sono una seccatura, e ci si sente come qualcosa di simile dovrebbe esistere già. Odio essere quello di reinventare una ruota di merda.

È qualcuno a conoscenza di qualcosa di simile? Ho guardato JODA, e sembra gettare le basi per questo, ma non sembra dare la piena funzionalità che voglio ..

risposta

7

Non penso ci siano iteratori prontamente fatti per joda-time o Java API di calendario per quella materia, tuttavia con joda è così facile che dovresti semplicemente andare con essa. Per esempio io stesso dopo la ri-familiarizzare con Joda Dopo alcuni mesi di pausa ho fatto questo in circa 10 minuti:

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 tempo è impressionante :-)

+0

Hai scosso il mio pomeriggio - grazie amico! –

+0

Anche se non è importante, voglio solo dire che questo è il secondo Iterator che abbia mai realizzato che supporti remove(), di solito ho trovato troppo ingombrante per supportarlo. – Esko

0

si potrebbe avere uno sguardo a Quartz che è stato progettato per la pianificazione del lavoro.

0

tl; dr

Facile, con java.time.

Per Giovedi 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

Le classi data-ora vecchi fastidiose in bundle con le prime versioni di Java sono ormai obsolete, soppiantato dalle classi java.time.

La classe LocalDate rappresenta un valore di sola data senza ora del giorno e senza fuso orario.

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

Per qualsiasi LocalDate, è possibile regolare nel verificarsi ordinale di un giorno della settimana all'interno dello stesso mese (es: terzo Giovedi, 2 ° Martedì, etc.). Specificare il giorno della settimana utilizzando DayOfWeek enum.

Per eseguire la regolazione, utilizzare le implementazioni TemporalAdjuster trovate nella classe TemporalAdjusters.

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

applicare tale regolazione per ogni LocalDate, producendo un altro oggetto LocalDate.

LocalDate thirdThursday = ld.with(thirdThursdayAdjuster) ; 

qualcosa di simile a un iteratore infinita fuori di esso (.Next() restituirebbe alla data successiva corrispondenza

semplicemente spostarsi da un LocalDate ad un altro. Si potrebbe chiamare LocalDate::addMonths.O se si tratta di un mese alla volta, utilizzare la classe 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) ; 
} 

Chi java.time

Il quadro java.time è costruito in Java 8 e versioni successive. Queste classi soppiantano le fastidiose classi di data legacy come java.util.Date, Calendar, & SimpleDateFormat.

Il progetto Joda-Time, ora in maintenance mode, consiglia la migrazione alle classi java.time.

Per ulteriori informazioni, vedere Oracle Tutorial. E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310.

Dove ottenere le classi java.time?

  • Java SE 8, Java SE 9, e più tardi
    • incorporato.
    • Parte dell'API Java standard con un'implementazione in bundle.
    • Java 9 aggiunge alcune funzionalità e correzioni minori.
  • Java SE 6 e Java SE 7
    • Molte delle funzionalità java.time è di back-porting per Java 6 .
  • Android
    • versioni successive di implementazioni fascio Android delle classi java.time.
    • Per Android precedente, il progetto ThreeTenABP si adatta a ThreeTen-Backport (menzionato sopra). Vedi How to use ThreeTenABP….

Il progetto ThreeTen-Extra java.time prolunga con classi aggiuntive. Questo progetto è un terreno di prova per possibili aggiunte future a java.time. È possibile trovare alcune classi utili come Interval, YearWeek, YearQuarter e more.

Problemi correlati