使用govaluate比较表达式中的日期值

时间:2017-07-03 20:06:57

标签: go expression rule-engine

我正在尝试使用govaluate构建规则引擎:https://github.com/Knetic/govaluate

这是我的代码:

package main

import (
    "github.com/Knetic/govaluate"
    "fmt"
)

func main()  {
    expression, err := govaluate.NewEvaluableExpression("first_name == 'Julian' && emp_id == 302 && birth_date >= '2016-12-12' && birth_date <= '2016-12-25'")

    parameters := make(map[string]interface{}, 8)
    parameters["first_name"] = "Julian"
    parameters["emp_id"] = 302
    parameters["birth_date"] = "2016-12-15"
    result, err := expression.Evaluate(parameters)

    if err != nil {
        fmt.Println("Error while evaluating the expression")
    }

    if result.(bool) {
        fmt.Println("Condition is evaluated to true")
    } else {
        fmt.Println("Condition is evaluated to false")
    }
}

在浏览govaluate类型文档(https://github.com/Knetic/govaluate/blob/master/MANUAL.md)时,我注意到了这个语句&#34; 任何可解释为日期的字符串文字(非参数)都将转换为float64表示形式约会的时间。&#34;

当我执行上述程序时,我看到结果为null的问题:

Error while evaluating the expression
panic: interface conversion: interface is nil, not bool

我的问题是日期值是否可以作为参数传递?由于我想在运行时比较日期值,因此需要此功能。

有没有办法实现它?可能是我的使用模式是错误的。请建议。

修改

expression, err := govaluate.NewEvaluableExpression("first_name == 'Julian' && emp_id == 302 && birth_date >= '2016-12-12' && birth_date <= '2016-12-25'")
dateFloat, _ := strconv.ParseFloat("2016-12-15", 64)
parameters["birth_date"] = dateFloat
result, err := expression.Evaluate(parameters)

将日期更改为浮动格式并调用Evaluate函数。现在条件被评估为假。但从逻辑上讲,2016-12-15属于2016-12-12和2016-12-25之间。该表达式应评估为true。

提前致谢!

2 个答案:

答案 0 :(得分:2)

the associated github issue交叉发布我的回答,以供将来的googlers使用;

库不会尝试将字符串参数解析为日期 - 它期望_search?filter_path=hits.hits._source将是该日期的Unix()值。这意味着您必须在将日期传递给govaluate之前解析日期。

如果您将birth_date作为REST API的一部分,我建议您使用一种特定的日期格式(例如ISO8601)并执行以下操作:

birth_date

答案 1 :(得分:1)

以下是工作解决方案:

package main

import (
    "github.com/Knetic/govaluate"
    "fmt"
    "time"
)

func main()  {
    expression, err := govaluate.NewEvaluableExpression("first_name == 'Julian' && emp_id == 302 && birth_date >= '2016-12-15' && birth_date <= '2016-12-25'")

    parameters := make(map[string]interface{}, 8)
    parameters["first_name"] = "Julian"
    parameters["emp_id"] = 302
    iso8601 := "2006-01-02"
    birthDate, err := time.ParseInLocation(iso8601, "2016-12-15", time.Local)
    parameters["birth_date"] = birthDate.Unix()
    result, err := expression.Evaluate(parameters)

    if err != nil {
        fmt.Println("Error while evaluating the expression")
    }

    if result.(bool) {
        fmt.Println("Condition is evaluated to true")
    } else {
        fmt.Println("Condition is evaluated to false")
    }
}

感谢图书馆老板和@RayfenWindspear帮我解决这个问题!真的很感激!