dousendun8411 2017-07-03 20:06
浏览 212
已采纳

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

I am trying to build a rule engine using govaluate: https://github.com/Knetic/govaluate

Here is my code:

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")
    }
}

While browsing through govaluate Types documentation (https://github.com/Knetic/govaluate/blob/master/MANUAL.md), I noticed this statement "Any string literal (not parameter) which is interpretable as a date will be converted to a float64 representation of that date's unix time."

When i execute the above program, i see an issue with result being null:

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

My question is whether date value can be passed in as a parameter? As i want to compare date values in runtime, this functionality would be needed.

Is there a way to achieve it? May be my usage pattern is wrong. Please suggest.

Edit:

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)

Changed the date to float format and invoked Evaluate function. Now the condition is evaluated to false. But logically, 2016-12-15 falls between 2016-12-12 and 2016-12-25. The expression should be evaluated to true.

Thanks in advance!

  • 写回答

2条回答 默认 最新

  • douao2019 2017-07-03 21:34
    关注

    Cross-posting my answer from the associated github issue, for future googlers;

    The library doesn't try to parse string parameters as dates - it expects that birth_date will be the Unix() value of that date. This means you'll have to parse the date before passing it to govaluate.

    If you're getting birth_date as part of a REST api, I'd suggest settling on one specific date format (such as ISO8601) and doing something like:

    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()
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题