计算处理时长 日期计算 SpringEL

计算处理时长 日期计算 SpringEL

要根据日期时间,计算处理时长。比如

{ 
	"创建时间": "2021-04-21",
	"结束时间": "2021-04-29",
	"开始处理时间": "2021-04-22 09:00:28",
	"处理完成时间": "2021-04-28 09:02:28" ,
    "总数": 17
}

要计算 “处理完成时间 - 开始处理时间” 的结果

         公式: "(#处理完成时间-#开始处理时间)/1000"

要计算 “结束时间 - 创建时间” 的结果

        公式:"(#结束时间-#创建时间)/(1000*60*60*24)"

处理思路:

1,如果字段是固定的,把相应的内容转换为时间戳,再进行计算

2,如果字段不是固定的,根据配置的来,这时候考虑使用SpringEl。

使用SpringEl的话:

    1,时间字符串转换为时间戳进行计算

    2,对应字段是中文的,要替换为英文才能计算。先提取要计算的字段,重新赋值,也替换公式的内容。最后进行计算。

直接上代码:

代码:

处理代码:

 public static void main(String[] args) {
        String beginTime = "2021-04-22 09:00:28";
        String endTime = "2021-04-22 09:10:33";
        String beginDate = "2021-04-22";
        String endDate = "2021-04-25";
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("开始处理时间", beginTime);
        dataMap.put("处理完成时间", endTime);
        dataMap.put("创建时间", beginDate);
        dataMap.put("结束时间", endDate);

        String formula1 = "(#处理完成时间-#开始处理时间)/1000";
        String formula2 = "(#结束时间-#创建时间)/(1000*60*60*24)";
        compulate(dataMap, formula1);
        System.out.println("==========");
        compulate(dataMap, formula2);

    }

    public static void compulate(Map<String, Object> dataMap, String formula){
        // 1,获取公式字段里面的字段
        List<String> calculateField = RegUtils.getFormulaParam(formula);
        // 引入新的参数
        String calculte = "calculte";
        AtomicInteger atomicInteger = new AtomicInteger(0);
        Map<String, String> matchFormulaMap = new HashMap<>();

        // 重置formula 和 数据类型
        String newParam;
        for (String s : ListUtils.emptyIfNull(calculateField)) {
            newParam = calculte + atomicInteger;
            matchFormulaMap.put(s, newParam); // 添加新的参数,用于数值处理的时候匹配
            formula = formula.replaceAll(s, newParam);
            atomicInteger.getAndIncrement();
        }

        // 日期转换
        changeFiledDataType(calculateField, matchFormulaMap, dataMap);
        System.out.println(dataMap);
        String  result = SpelExpressionUtils.parseExpression(dataMap, formula, "0");
        System.out.println(result);
    }

    private static void changeFiledDataType(List<String> calculateField, Map<String, String> matchFormulaMap,
                                            Map<String, Object> dataMap) {
        String value, matchKey;
        for (String s : ListUtils.emptyIfNull(calculateField)) {
            value = MapUtils.getString(dataMap, s);
            matchKey = matchFormulaMap.get(s);
            if (StringUtils.isNotBlank(value) && DateTimeUtils.isValidDateStr(value)) {// 日期类型转换为long类型
                dataMap.put(matchKey, DateTimeUtils.toLongDateStr(value));
            } else {
                dataMap.put(matchKey, dataMap.get(s));
            }
        }
    }

工具类:

正则的参考 匹配中文

日期的参考 字符串转时间戳

SpringEl的:

public class SpelExpressionUtils {

    private static final ExpressionParser PARSER = new SpelExpressionParser();

    public static ExpressionParser getParser() {
        return PARSER;
    }

    private SpelExpressionUtils() {
    }

    public static String parseExpression(Map<String, Object> data, String formula) {
        return parseExpression(data, formula, "0.00");
    }

    public static Double parseDoubleExpression(Map<String, Object> data, Expression expression) {
        EvaluationContext ctx = new StandardEvaluationContext();
        if (Objects.nonNull(data)) {
            data.forEach(ctx::setVariable);
        }
        return expression.getValue(ctx, Double.class);
    }
 
    public static Double parseDoubleExpression(Map<String, Object> data, String formula) {
        Expression expression = PARSER.parseExpression(formula);
        return parseDoubleExpression(data, expression);
    }

    public static String parseExpression(Map<String, Object> data, String formula, String pattern) {
        try {
            Double expressionResult = parseDoubleExpression(data, formula);
            if (Objects.nonNull(expressionResult)) {
                return decimalFormat(expressionResult, pattern);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }


    private static String decimalFormat(Double value, String pattern) {
        if (StringUtils.isBlank(pattern)) {
            pattern = "0";
        }
        DecimalFormat df = new DecimalFormat(pattern);
        df.setRoundingMode(RoundingMode.HALF_UP);
        return df.format(value);
    }

结果:

{开始处理时间=2021-04-22 09:00:28, 创建时间=2021-04-22, calculte1=1619053228000, 处理完成时间=2021-04-22 09:10:33, 结束时间=2021-04-25, calculte0=1619053833000}


605

==========

{开始处理时间=2021-04-22 09:00:28, 创建时间=2021-04-22, calculte1=1619020800000, 处理完成时间=2021-04-22 09:10:33, 结束时间=2021-04-25, calculte0=1619280000000}

3

如果要加单位,就再拼接

总结:

    计算处理时长,动态处理的话,还是使用SpringEl比较好处理。可以根据公式自行变化。一般公式是配置在数据库,读取配置再进行处理。

   复杂的例子代码参考:计算处理时长

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天狼1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值