Getting Started

The source code , being rather scarce, is an excellent place to start kicking the tires. There's not much of it (a Good Thing), and JavaDocs have been carefully written for the public interfaces. Also, basic usage patterns can be gleaned from the JUnit tests which are reasonably comprehensive.

Intro to Temporal Expressions

Based on patterns created by Martin Fowler , temporal expressions allow you to define points or ranges in time using set expressions . For example, say you wanted to schedule an event that occurred annually on the last Thursday of every August.

You could, of course, do something like this:

List someDates = new ArrayList();            

someDates.add((new GregorianCalendar(2002,7,29)).getTime());

someDates.add((new GregorianCalendar(2003,7,28)).getTime());

someDates.add((new GregorianCalendar(2004,7,29)).getTime());

...etc.
    

This is fine for two or three years, but what about for 20 years? What if you want to say every Monday, Tuesday and Friday, between 3 and 5pm for the next two years? As you can see, this gets ugly fast.

Using TemporalExpression s provides a reasonably straightforward API for succinctly defining a given set of dates and/or times:

//Avoid using an enumerated list of dates to build a schedule.
//Rather, use set expressions to build a matching set:

//Last Thursday of the month (any month).
TemporalExpression dayInMonthTE = new DayInMonthTE(5, -1);

//From July through August of any year (year can also be specified). 
TemporalExpression rangeEachYearTE1 = new RangeEachYearTE(7, 8);

//From August through September of any year.     
TemporalExpression rangeEachYearTE2 = new RangeEachYearTE(8, 9);

//A temporal expression for matching elements of sets which overlap.
//Concrete type is used because CollectionTE defines the add() method not
//specified in the TemporalExpression interface.
CollectionTE intersectionTE = new IntersectionTE();

//This expression says: last Thursday in August, please 
intersectionTE.add(dayInMonthTE).add(rangeEachYearTE1).add(rangeEachYearTE2);

//A TimePoint is just a java.util.Date that makes it easier to specify 
//and compare date precision; e.g. date vs. date and time, etc.

//TimePoint => last Thursday in August, 2003
System.out.println(intersectionTE.includes(new TimePoint(2003, 8, 28)));  //true

//TimePoint => last Thursday in August, 2002
System.out.println(intersectionTE.includes(new TimePoint(2002, 8, 29)));  //true

//These (hopefully) will not match:

//TimePoint => last Wednesday in August
System.out.println(intersectionTE.includes(new TimePoint(2003, 8, 27)));  //false

//TimePoint => July 28th
System.out.println(intersectionTE.includes(new TimePoint(2003, 7, 28)));  //false

//A DateRange is just the span of time between two TimePoints.
//An ArbitraryDateRangeTE is for specifying one or more arbitrary periods of time (i.e. not recurring).
//So, this expression matches the following time frame:
//11:20pm, Thursday, August 29th, 2002 to 12:15pm, Friday, August 30th, 2002
ArbitraryDateRangeTE arbitraryDateRangeTE =
    new ArbitraryDateRangeTE(
        new DateRange(
            new TimePoint(2002, 8, 29, 23, 20),
            new TimePoint(2002, 8, 30, 0, 15)));

//DifferenceTE implements set exclusion functionality. In other words, 
//the dates and times matched by expr1 - expr2
//specified as constructor arguments like so: new DifferenceTE(expr1,expr2)
CollectionTE differenceTE = new DifferenceTE(intersectionTE, arbitraryDateRangeTE);

//11:19pm, Thursday, August 29th, 2002
System.out.println(differenceTE.includes(new TimePoint(2002, 8, 29, 23, 19)));  //true

//11:20pm, Thursday, August 29th, 2002
System.out.println(differenceTE.includes(new TimePoint(2002, 8, 29, 23, 20)));  //false!
    

These are simple examples, but they demonstrate how TemporalExpressions can be used to define patterns of occurrence and recurrence. Additionally, there are several other TemporalExpressions, and once you get the hang of it, it's easy to write your own.

See Also: