当前位置: 首页 > 工具软件 > Aviator > 使用案例 >

Aviator 特殊处理时间字符串

严高峻
2023-12-01

在使用Aviator写脚本的时候,要计算两个时间字符串,得到处理时长。处理时间的时候,如果时间字符串是不固定。想传时间字符串进去,然后进行替换计算该如何处理呢?

处理思路:

  用“.getTime()”进行标记这个是时间字符串,要把字符串时间替换为日期时间。

  如果结束时间,则处理时长字段为空""

代码

// 把时间字符串转换为时间
public static Date strToDateTime(String time) {
    Date dateTime = null;
    try {
        dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(time);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return dateTime;
}

// 正则表达式 用于获取 $xxx.yyyy.getTime() 中 yyyy的内容,
public static List<String> getMatchGetTime(String expression, String mark) {
    String pattern = "\\$" + mark + "\\.([\\[\\]0-9a-zA-Z_.]*)" + "\\.getTime\\(\\)";
    Pattern p = Pattern.compile(pattern);
    Matcher m = p.matcher(expression);
    List<String> column = new ArrayList<>();
    while (m.find()) {
        column.add(m.group(1));
    }
    return column;
}

// 特殊处理时间 使用.getTime() 作为要把该字符串之间转为Date时间进行处理
// 用$row 表示当前数据, $param 表示参数
public static  void testDateGetTimeCalculateUnitByGetTime(Map<String, Object> data, Map<String, Object> param) {
    String expression = "let st = $row.startTimeStr.getTime(); let startTime = getTime(st);  " +
            "let ed = $row.endTimeStr.getTime(); let endTime = getTime(ed);  " +
            "return '处理人:'+$row.staffName+',处理时长为:'+(endTime - startTime)/$param.divisor+$param.unit;";
    // 获取到带getTime()字段的内容
    List<String> matchGetTime = getMatchGetTime(expression, "row");
    // 对时间和表达式进行替换
    boolean calcuate = true; // 判断是否要计算,如果有时间为空,就不进行计算,直接赋值为空
    Map<String, Object> env = new HashMap<>();
    // 复制一份数据,用于后面put要计算的date值
    Map<String, Object> rowParam =  new HashMap<>(data);
    env.put("$row", rowParam);
    env.put("$param", param);
    Object result;
    if (CollectionUtils.isNotEmpty(matchGetTime)) {
        for (String e : ListUtils.emptyIfNull(matchGetTime)) {
            String dateResult = rowParam.get(e).toString();
            if (StringUtils.isBlank(dateResult)) {// 如果没有对应的值就不进行计算了
                calcuate = false;
                break;
            } else {
                result = strToDateTime(dateResult);
            }
            // 添加新的名字,用于计算
            String reName = e + "Calculate";
            // 替换表达式的内容,去掉.getTime(), 不然无法识别
            expression = expression.replace(e + ".getTime()", reName);
            rowParam.put(reName, result);
        }

    }

    if (calcuate) {
        // 启用基于反射的方法查找和调用
        AviatorEvaluator.setFunctionMissing(JavaMethodReflectionFunctionMissing.getInstance());
        Expression compiledExp = AviatorEvaluator.compile(expression);
        try {
            result = compiledExp.execute(env);
        } catch (Exception e) {
            e.printStackTrace();
            result = "";
        }
    } else {
        result = "";
    }
    data.put("calculte", result);

}
public static void main(String args[]) {
    Map<String, Object> data = new HashMap<>();
    String startTime = "2022-03-25 10:25:25";
    String endTime = "2022-03-25 11:25:25";
    data.put("startTimeStr", startTime);
    data.put("endTimeStr", endTime);
    data.put("staffName", "小李");

    Map<String, Object> param = new HashMap<>();
    param.put("divisor", 1000);
    param.put("unit", "s");

    System.out.println("结束时间正常:");
    testDateGetTimeCalculateUnitByGetTime(data,param);
    System.out.println(JSON.toJSON(data));

    System.out.println("结束时间异常:");
    data.put("endTimeStr", "");
    testDateGetTimeCalculateUnitByGetTime(data,param);
    System.out.println(JSON.toJSON(data));

}

可能的错误

结束时间正常:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/beanutils/BeanIntrospector
	at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:73)
	at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:136)
	at com.ffcs.iod.ms.workflow.report.config.AviatorTest.getDateGetTimeCalculateUnitByGetTime(AviatorTest.java:251)
	at com.ffcs.iod.ms.workflow.report.config.AviatorTest.testDateGetTimeCalculateUnitByGetTime(AviatorTest.java:277)
	at com.ffcs.iod.ms.workflow.report.config.AviatorTest.main(AviatorTest.java:442)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.beanutils.BeanIntrospector
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 5 more

原因: 漏了对应commons-beanutils的jar包

处理:引入commons-beanutils的包

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

总结:

   在用Aviator处理时间的时候,把字符串时间转换时间,再替换表达式里面对应的值,再进行计算和处理。 如果没有指定具体时间字段,需要特殊处理,比如上面的使用“.getTime()”进行识别和表达式替换。 对于一些脚本处理不来的内容,使用java进行处理,再进行替换。

 类似资料: