使用 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 帮助我解决这个问题!非常感谢!
我正在尝试使用 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 帮助我解决这个问题!非常感谢!