Uploaded image for project: 'Drools'
  1. Drools
  2. DROOLS-7637

date-effective and date-expires inconsistency. date-effective bad design

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • None
    • 8.44.0.Final
    • core engine
    • None
    • NEW
    • NEW
    • ---
    • ---

      Hi team, thanks for your hard work!

      Recently I tried date-effective feature and got some unexpected behavior. Here is my findings.

       

      date-effective works as designed (though not good as for me):

      A string containing a date and time definition. The rule can be activated only if the current date and time is after a date-effective attribute.
      
      Example: date-effective "4-Sep-2018"

      It takes 4-Sep-2018 as date in system time zone, takes time at start of the day and get milliseconds which represent a time since 1970 to deal with the clock. Indeed, a millisecond after this threshold, rule gets activated.

      date-expires doesn't work the same way, though stated the same:

      A string containing a date and time definition. The rule cannot be activated if the current date and time is after the date-expires attribute.
      
      Example: date-expires "4-Oct-2018" 

      at 2018-10-04T00:00:00 local time zone rule is no longer gets activated.

      The inconsistency is a bug (date-expires doesn't work according to documentation), but I would question the design of "The rule can be activated only if current date and time is after a date-effective attribute". Why so? Because the notion of a 'local date' or a 'business day' is usually implied a midnight, not midnight + 1ms.

      All three gives the same value in my time zone:

      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      System.out.println(sdf.parse("2018-09-04").getTime());
      System.out.println(LocalDate.parse("2018-09-04").atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli());
      System.out.println(ZonedDateTime.parse("2018-09-04T00:00:00+02").toInstant().toEpochMilli());

      When I encounter date-effective "4-Sep-2018" in drl file, I would expect the rule to be activated starting 2018-09-04T00:00:00 local time zone. In fact it triggers next millisecond at 2018-09-04T00:00:00.001. Which brakes java way of doing things as for me.

      Here is the test

      public class Trade {
          public String tradeDate;
          public boolean isEligible;
          public Trade(String tradeDate) {
              this.tradeDate = tradeDate;
          }
      }
      
      @Test
      public void testDateEffective() throws ParseException {
          KieSession session = //...
          SessionPseudoClock clock = session.getSessionClock();
          SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
          
          Trade trade3 = new Trade("2018-09-03");
          Trade trade4 = new Trade("2018-09-04"); // date-effective
          Trade trade5 = new Trade("2018-09-05");
          Trade trade6 = new Trade("2018-09-06"); // date-expires
          Trade trade7 = new Trade("2018-09-07");
          
          clock.advanceTime(simpleDateFormat.parse(trade3.tradeDate).getTime() - clock.getCurrentTime(), MILLISECONDS);
          session.insert(trade3);
          session.fireAllRules();
          assertEquals(false, trade3.isEligible);
          
          clock.advanceTime(simpleDateFormat.parse(trade4.tradeDate).getTime() - clock.getCurrentTime(), MILLISECONDS);
          // clock.advanceTime(1, MILLISECONDS);
          session.insert(trade4);
          session.fireAllRules();
          assertEquals(true, trade4.isEligible); // fails, works next millisecond
          
          clock.advanceTime(simpleDateFormat.parse(trade5.tradeDate).getTime() - clock.getCurrentTime(), MILLISECONDS);
          session.insert(trade5);
          session.fireAllRules();
          assertEquals(true, trade5.isEligible);
          
          clock.advanceTime(simpleDateFormat.parse(trade6.tradeDate).getTime() - clock.getCurrentTime(), MILLISECONDS);
          session.insert(trade6);
          session.fireAllRules();
          assertEquals(false, trade6.isEligible); // passes, surprisingly (date-expires has different logic than date-effective, but why?)
          
          clock.advanceTime(simpleDateFormat.parse(trade7.tradeDate).getTime() - clock.getCurrentTime(), MILLISECONDS);
          session.insert(trade7);
          session.fireAllRules();
          assertEquals(false, trade7.isEligible);
      }

      and the rule file for the test:

      rule "Trade Eligibility"
      date-effective "04-Sep-2018"
      date-expires "06-Sep-2018"
      when
          $trade : Trade()
      then
          $trade.isEligible = true;
      end

      I was not able to put 9.44.0.Final into 'Affects Version' but it works the same way in both.

       

       

       

              mfusco@redhat.com Mario Fusco
              madamovych Mykhaylo Adamovych (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated: