Hi Dirk,
Maybe you can use eval like this:
when
ObjectWithEventDates( $SomeEventDate:SomeEventDate)
eval( $SomeEventDate > (now()))
eval( $SomeEventDate < (weeksFromNow(2)) )
then
assertLogical(new UpcomingFooEvent());
end
What is inside eval should be re-evaluated each time, not cached.
/Tomas
Dirk Bergstrom wrote:
Michael Neale was heard to exclaim, On 11/27/06 05:00:
I agree. We have talked about this before, we are looking at
incorporating Joda Time which has constructs (and a great Date/Time API)
eventually to support that sort of declarative temporal rules.
That might be overkill for what I need to do.
If you could suggest some sample drl level syntax that would express
what you need, perhaps we may be able to do this in another way in the
meantime (we already have some limited treatment of dates, no reason why
it cant be extended).
I spent most of the day trying to write a rule that would do what I want with
existing syntax. After far too much work, I finally arrived at (roughly) this:
function Date now() {
return new Date();
}
function Date weeksFromNow(int num) {
return new Date(System.currentTimeMillis() + (86400 * 7 * num);
}
rule "SomeEvent is less than two weeks away"
when
ObjectWithEventDates( SomeEventDate > (now()),
SomeEventDate < (weeksFromNow(2)) )
then
assertLogical(new UpcomingFooEvent());
end
So it ends up that all I need is a set of convenience methods that express
intervals. If anyone saw all the convoluted things I tried on the way to
this, I'd die of embarrassment...
Hmmm, wait... The above fails to work after the first time through, since the
values of now() and weeksFromNow(2) are anything but time-constant. So I
guess the other thing that's required is some way to inform drools that these
values are not constant. As a simple hack, you could use curly braces (or
square brackets, or something like "(? expr() )") to indicate a
non-time-constant return value expression (and the same for return value
operators). Or you could use a keyword such as "changing", "inconstant" or
"varying" (or you could allow eval in constraints, but that might get messy).
Or you could create two keywords with syntax like:
interval(<number> millis|seconds|minutes|hours|days|weeks|years ago|away)
now()
So my constraint would become:
ObjectWithEventDates( SomeEventDate > now(),
SomeEventDate < interval(2 weeks away) )
Luckily, the inconstancy doesn't matter for me because (for various reasons) I
have to modify() ObjectWithEventDates every time I run the rules.
As always, patches are welcome !
Here's my class full of convenience methods. Not really what you're looking
for, but hey, it's something...
public class DateIntervals {
/**
* @return Current time.
*/
public static Date now() {
return new Date();
}
/**
* @param days
* @return Date as of 'days' days ago.
*/
public static Date daysAgo(int days) {
return new Date(System.currentTimeMillis() -
(days * 1000 * 60 * 60 * 24L));
}
/**
* @param days
* @return Date as of 'days' from now.
*/
public static Date daysFromNow(int days) {
return new Date(System.currentTimeMillis() +
(days * 1000 * 60 * 60 * 24L));
}
// Etc. for millis, seconds, hours, weeks and years...
/*
If I were implementing this, I'd just document the fact that intervals don't
account for things like daylight savings and leap years. Trying to get those
"correct" would take 10x the effort, and probably wouldn't really do anyone
any good. Let the folks that need to obsess over minutiae implement their own
obsessive code, and let the rest of us have something that works (imho, the
problem with Java's Date handling is the obsession with obscure details at the
expense of usability).
*/
}
On 11/23/06, *Dirk Bergstrom* <[EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]>> wrote:
Most of the rules I need to write have a date-based
component. Examples:
If it is less than seven days before user's birthday...
If it is more than three hours since user's last meal...
If it is between four and seven days before user's next appointment...
There doesn't appear to be a way to do this without an eval and some
behind-the-scenes complexity. Am I missing something?
It would be nice if the syntax natively supported date interval
comparisons.
Since the current time is always changing, any constraint using one
of these
constructions would have to be re-evaluated every time (just like an
eval),
but it would at least be easy to write the rules.
--
Dirk Bergstrom [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>
_____________________________________________
Juniper Networks Inc., Computer Geek
Tel: 408.745.3182 Fax: 408.745.8905
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email