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

Compare date values in expression using govaluate

我正在尝试使用 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 Types 文档 (https://github.com/Knetic/govaluate/blob/master/MANUAL.md) 时,我注意到这个语句“任何可解释为日期的字符串文字(不是参数)将被转换为 float64 表示形式该日期的 Unix 时间。"

当我执行上面的程序时,我看到一个结果为空的问题:

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 之间。表达式应评估为真。

提前致谢!

交叉发布我在 the associated github issue 中的回答,以供未来的 google 员工使用;

库不会尝试将字符串参数解析为日期 - 它期望 birth_date 将是该日期的 Unix() 值。这意味着您必须先解析日期,然后再将其传递给 govaluate。

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

var birthDateString string // <-- the birth_date string you get from the request

iso8601 := "2006-01-02T15:04:05Z0700"

birthDate, err := time.ParseInLocation(iso8601, birthDateString, 
time.Local)
parameters["birth_date"] = birthDate.Unix()

这是可行的解决方案:

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 帮助我解决这个问题!非常感谢!