Friday, May 6, 2011

Java date iterator factory, with rules specifying how to calculate the intervals

I am looking for a Java class where I can specify a set of date rules, such as "every 3rd sunday" and "the first occurrence of a monday every second month". I want to be able to get something like an infinite iterator out of it (.next() would return the next date matching the rules set).

I think I'd be able to build it myself - but calendars are a hassle, and it feels like something similar should exist already. I hate being the one to reinvent a crappier wheel.

Is anyone aware of something like this? I have been looking at JODA, and it seems to lay the groundwork for it, but does not appear to give the full functionality I want..

From stackoverflow
  • I don't think there's any readily made iterators for joda-time or Java Calendar API for that matter, however with joda it's so easy that you should just go with it. For example after re-familiarizing myself with joda after a few months pause I made this in about 10 minutes:

    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 is awesome :-)

    Jacob Hansson : You rocked my afternoon - thanks mate!
    Esko : While not important at all, I just want to say that this is the second Iterator I've ever made which supports remove(), usually I've found it to be too cumbersome to support it.
  • My company has something very much like you want but it's for .NET so it probably won't do you any good.

  • You could have a look at Quartz which is designed for job scheduling.

No comments:

Post a Comment