java 比较流口水中的日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33494628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 21:45:49  来源:igfitidea点击:

Compare dates in drools

javajbossdroolsdrools-guvnordrools-fusion

提问by Hasitha

My rule file as below,

我的规则文件如下,

import com.springapp.mvc.model.Person; 
dialect "java"
rule "4" 
    when
        $person:Person(((date > "20-Jan-2015") && (date < "20-Dec-2015")) && (call_count >= "299"))
    then
        System.out.println("Beep");
end

I added following person object and fire rules as below,

我添加了以下人员对象和火规则如下,

Person person = new Person();
person.date = "20-Feb-2015";
person.call_count = 400;
kSession.insert(person);
int fires = kSession.fireAllRules();

But it didn't print "Beep". I think conditions are not matched but I can't understand why this happen. How can I compare dates in drools?

但它没有打印“哔”。我认为条件不匹配,但我不明白为什么会发生这种情况。如何比较流口水中的日期?

My actual rule set,

我的实际规则集,

package Customer_Loyalty_Categorization;
import com.springapp.mvc.model.Person; 
dialect "java"

rule "4" 
    when
        $person:Person(((date > "10-Nov-2015") && (date < "10-Dec-2015")) && (call_count >= "299"))
        $person:Person(((date > "10-Nov-2015")&&(date < "30-Dec-2015")) && (call_count >= "299"))
    then
        System.out.println("Point rule runs.");
        $person.points = ($person.call_count)*0.2;
end

rule "6" 
    when
        $person:Person(call_count >= "599")
    then
        System.out.println("Category rule runs.");
        $person.setCategory('PLATINUM');
end

And after changing type of the date variable of the person I got following exception,

在更改人员的日期变量类型后,我遇到了以下异常,

java.lang.RuntimeException: Unable to Analyse Expression date > "20-Nov-2015":
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String]
[Near : {... date > "20-Nov-2015" ....}]
                    ^
[Line: 8, Column: 8] : [Rule name='4']

Unable to Analyse Expression date < "20-Dec-2015":
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String]
[Near : {... date < "20-Dec-2015" ....}]
                    ^
[Line: 8, Column: 8] : [Rule name='4']

Unable to Analyse Expression date > "01-Jan-2015":
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String]
[Near : {... date > "01-Jan-2015" ....}]
                    ^
[Line: 40, Column: 8] : [Rule name='1']

Unable to Analyse Expression date < "07-Jan-2015":
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String]
[Near : {... date < "07-Jan-2015" ....}]
                    ^
[Line: 40, Column: 8] : [Rule name='1']

Unable to Analyse Expression date > "01-Jan-2015":
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String]
[Near : {... date > "01-Jan-2015" ....}]
                    ^
[Line: 48, Column: 8] : [Rule name='2']

Unable to Analyse Expression date < "07-Jan-2015":
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String]
[Near : {... date < "07-Jan-2015" ....}]
                    ^
[Line: 48, Column: 8] : [Rule name='2']

Unable to Analyse Expression date > "05-Jan-2015":
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String]
[Near : {... date > "05-Jan-2015" ....}]
                    ^
[Line: 48, Column: 8] : [Rule name='2']

Unable to Analyse Expression date < "10-Jan-2015":
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String]
[Near : {... date < "10-Jan-2015" ....}]
                    ^
[Line: 48, Column: 8] : [Rule name='2']

I'm generating rules as set of strings and convert them into knowledgebase using following function,

我将规则生成为一组字符串,并使用以下函数将它们转换为知识库,

public void createKnowledgeBase(){
        String ruleSet = loadRuleSet();//generate rules as strings.
        try {
            System.out.println(ruleSet);
            long start = System.currentTimeMillis();
            if(ruleSet!=null){
                KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
                Resource myResource = ResourceFactory.newReaderResource(new StringReader(ruleSet));
                knowledgeBuilder.add(myResource, ResourceType.DRL);
                if (knowledgeBuilder.hasErrors()) {
                    throw new RuntimeException(knowledgeBuilder.getErrors().toString());
                }
                knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
                knowledgeBase.addKnowledgePackages(knowledgeBuilder.getKnowledgePackages());
            }
            long finish = System.currentTimeMillis();
            System.out.println("Execution time = " + (finish-start) + " milliseconds.");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

采纳答案by laune

Apparently you have

显然你有

class Person {
    String date;
    // ...
}

So that

以便

when
    $person:Person(((date > "20-Jan-2015") ...

results in a string (!) comparison of

导致字符串 (!) 比较

"20-Feb-2015" > "20-Jan-2015" && "20-Feb-2015" < "20-Dec-2015"

which may even work at times, but mostly it wont. You should use

这有时甚至可能起作用,但大多数情况下不会。你应该使用

class Person {
    java.util.Date date;
    // ...
}

You need to change

你需要改变

person.date = new Date( 115, 1, 20 ); // or, preferably, parse a string 

but you can leave the rule as it is; Drools will convert a string to a Date value (provided it corresponds to your locale setting).

但你可以保持规则不变;Drools 会将字符串转换为日期值(前提是它对应于您的语言环境设置)。

LaterAfter some experiments, I find that 6.3.0 (and probably earlier versions) have a rather weird behaviour when compiling comparisons of java.util.Date to String.

后来经过一些实验,我发现 6.3.0(可能还有更早的版本)在编译 java.util.Date 与 String 的比较时有一个相当奇怪的行为。

rule x1 when
  Person(date > "10-Jan-2000")              // OK
  Person($date:date, date > "10-Jan-2000")  // OK
  Person($date:date, $date > "10-Jan-2000") // Error (types incompatible)

It is absolutely confusing when a programmer may not rely on the fact that a bound variable behaves like the property to which it is bound.

当程序员可能不依赖绑定变量的行为与它绑定的属性一样这一事实时,这绝对令人困惑。

Finally:Don't use public fields in your fact classes. Stay with the Java Beans model and declare getters and setters.It turns out that Drools isn't using the automatic conversion from String to java.util.Date when a (public) instance variable itself is accessed due to the lack of a getter.

最后:不要在事实类中使用公共字段。继续使用 Java Beans 模型并声明 getter 和 setter。事实证明,由于缺少 getter,当访问(公共)实例变量本身时,Drools 没有使用从 String 到 java.util.Date 的自动转换。

回答by ccc

You can try with org.apache.commons.lang.time.DateUtils. I got same kind of problem and this one worked for me, may be will work on yours.

您可以尝试使用org.apache.commons.lang.time.DateUtils. 我遇到了同样的问题,这个对我有用,可能对你有用。

import org.apache.commons.lang.time.DateUtils; 

$person: Person((date > DateUtils.parseDate("20-01-2015", "dd-MM-yyyy") && date < DateUtils.parseDate("20-12-2015", "dd-MM-yyyy")) && (call_count >= "299"));