tags:

views:

650

answers:

5

I want to have objects that define partial dates / times similar to the entries in Unix crontabs, i. e. "every first day in any month" etc.

These objects are going to be compared to Calendar objects to see if they match.

I was about to write my own "TimePattern" class but it would have to contain a lot of logic like checking if the field values were inside legal bounds (hour between 0 and 23 etc) that I felt would be inside classes like Calendar anyway.

So, now I'm just using a (nonlenient) Calendar object with some fields unset and I want to compare them with fully set Calendar objects that represent a fixed point in time. Should I

  • write my own method that goes through the relevant fields and checks for "equal or unset"
  • extend a (Gregorian)Calendar class to contain a "matchWith" method
  • use some comparison mechanism that's already there (in the Calendar class), but that I've overlooked so far
A: 

You could create a set of Comparators - MinuteMatch, HourMatch, etc, and use them to compare the two dates?

JeeBee
+1  A: 

How about using a Quartz Cron Expression?

Steve B.
A: 

One solution that I've used in the past is to write a DateFormatter that will format dates with only the fields that you want, then compare the resulting Strings. For example, it's quite common not to care about the time component, only dates, so you might do something like this:

public boolean sameDate(Calendar c1, Calendar c2)
{
    DateFormat datesOnly = new SimpleDateFormatter("yyyy-MM-dd");
    return datesOnly.format(c1.getTime()).equals(datesOnly.format(c2.getTime()));
}

It's probably not the best implementation if you're going to create a new library but it works pretty well for other cases.

Outlaw Programmer
A: 

Would Google's RFC-2445 be of any use? It's a date recurrence calculator that lets you easily do the "first monday of every third month" semantics.

banjollity
A: 

This is what I did eventually:

public class CalendarMatch<T extends Calendar> {
    private T _dt;

    public CalendarMatch(T dt) {
        this._dt = dt;
    }

    public boolean fMatches(T dtCmp)
    {
        int[] rgChecks = {
                           Calendar.HOUR_OF_DAY,
                           Calendar.MINUTE,
                           Calendar.SECOND,
                           Calendar.DAY_OF_MONTH,
                           Calendar.MONTH,
                           Calendar.YEAR,
                           Calendar.DAY_OF_WEEK
                         };
        for (int ixField : rgChecks) {
            // if any field in our partial date is set
            // but does not equal its counterpart, it's not a match
            if (this._dt.isSet(ixField) && dtCmp.get(ixField) != this._dt.get(ixField)) {
                return false;
            }
        }
        // otherwise, it is
        return true;
    }
}
Hanno Fietz
How is this different, or better, than the default Calendar.equals(Calender) method?
banjollity
Calendar.equals is much stricter and will not handle the unset fields as I would like it to. See also:http://java.sun.com/javase/6/docs/api/java/util/Calendar.html#equals(java.lang.Object)I'm not really looking for an equal date, but for one that matches my "template", or partial date.
Hanno Fietz