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

Reply via email to