java语言时间表达式引擎

自己用的一个需要解析时间格式表达式的小工具类: /** * <pre> * Copyright CDC [2000-2015] * </pre> */package org.kanpiaoxue.commons.utils;import org.apache.commons.lang3.StringUtils;import org...
摘要由CSDN通过智能技术生成

自己用的一个需要解析时间格式表达式的小工具类:

 

/**
 * <pre>
 * Copyright CDC [2000-2015]
 * </pre>
 */
package org.kanpiaoxue.commons.utils;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <pre>
 * DateExpressionEngine.java
 * @author kanpiaoxue<br>
 * @version 1.0
 * Create Time 2015年6月4日 下午7:16:02<br>
 * Description : 时间表达式引擎
 * </pre>
 */
public class DateExpressionEngine {

    /**
     * <pre>
     * @param needProcessString 需要处理的字符串
     *  里面可以含有任意多个时间表达式
     *  格式:dateFormat[,offset]}
     *  dateFormat: 符合java的java.text.DateFormat规范的表达式
     *  DateUnit 时间格式单位:[注意大小写]
     *      y   :   year
     *      M   :   Month
     *      d   :   day
     *      w   :   week
     *      H   :   Hour
     *      m   :   minute
     *
     *  [重点]这里的格式有两种,一种是一般日期表达式,一种是特殊表达式
     *
     *  一、一般日期表达式:
     *  offset的表达式:(-)?number+DateUnit
     *  offset的正则表达式: ^((?:-)?\\d+?)([y,M,w,d,H,m])$
     *
     *   example:
     *      ${MM} ${MMdd} ${MM/dd} ${HH} ${HHmm}
     *      ${yyyyMMdd} ${yyyy-MM-dd} ${yyyy/MM/dd}
     *      ${yyyyMMddHH} ${yyyy-MM-dd HH} ${yyyy/MM/dd HH}
     *      ${yyyyMMddHHmm} ${yyyy-MM-dd HH:mm} ${yyyy/MM/dd HH:mm}
     *      ${yyyyMMdd,-1y} ${yyyy-MM-dd,-1y} ${yyyy/MM/dd,-1y}
     *      ${yyyyMMdd,-1M} ${yyyy-MM-dd,-1M} ${yyyy/MM/dd,-1M}
     *      ${yyyyMMdd,1d} ${yyyy-MM-dd,1d} ${yyyy/MM/dd,1d}
     *      ${yyyyMMddHH,1H} ${yyyy-MM-dd HH,1H} ${yyyy/MM/dd HH,1H}
     *      ${yyyyMMdd,1w} ${yyyy-MM-dd,1w} ${yyyy/MM/dd,1w}
     *      ${yyyyMMddHHmm,10m} ${yyyy-MM-dd HH:mm,10m} ${yyyy/MM/dd HH:mm,10m}
     *
     * 二、特殊表达式
     *  用来计算:季度初/末,月初/末,周初/末(也就是周一和周日)
     *  offset的表达式:position+DateUnit
     *  offset的正则表达式:^([F,f,E,e])([M,w,W,q,Q])$
     *  ------------------
     *  F,f means: first
     *  E,e means: end
     *  ------------------
     *  M : Month
     *  w,W : Week
     *  q,Q : Quarter
     *
     * @param dateValue 时间的字符串,格式要求 yyyyMMdd,yyyyMMddHH,yyyyMMddHHmm
     * @return 经过计算之后的字符串
     * </pre>
     */
    public static String formatDateExpression(String needProcessString, String dateValue) {
        Preconditions.checkArgument(StringUtils.isNotBlank(needProcessString));
        Preconditions.checkArgument(StringUtils.isNotBlank(dateValue));
        Preconditions.checkArgument(DATE_PATTERN.matcher(dateValue).matches(),
                "dateValue is unexpect format:%s. "
                        + "Required min length is 8, like : 20150101. %s's length is : %s", dateValue,
                        dateValue, dateValue.length());

        Matcher m = PATTERN.matcher(needProcessString);
        /**
         * 如果找到时间表达式则进行替换,如果找不到,则不进行处理
         */
        while (m.find()) {
            String expression = m.group(2);
            /**
             * <pre>
             * ${expression} is group(1) , as:  ${yyyyMMdd,-1y} , ${yyyyMMdd,FQ}
             * expression is group(2) , as: yyyyMMdd,-1y , yyyyMMdd,FQ
             * </pre>
             */
            int start = m.start(1);
            int end = m.end(1);
            // expressionWrapper : ${yyyyMMdd,-1y} , ${yyyyMMdd,FQ}
            String expressionWrapper = needProcessString.substring(start, end);
            // replaceMent : 20150101 201501012359
            // 得到正确的时间字符串
            String replaceMent = getCorrectDateString(expression, dateValue);
            // 替换表达式为正确的时间字符串
            needProcessString = StringUtils.replace(needProcessString, expressionWrapper, replaceMent);
            // find next
            m = PATTERN.matcher(needProcessString);
        }
        return needProcessString;
    }

    private static String getCorrectDateString(String express, String dataVersionNo) {
        // 将表达式切分开
        List<String> lst = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(express);
        int size = lst.size();
        Preconditions.checkArgument(size <= 2, "unexpected expression format:%s", express);
        // 得到世界表达式的格式化部分
        String format = lst.get(0);
        // 将版本号的字符串转换为 DateTime 对象
        DateTime dateTime = parseForDataVersionNo(dataVersionNo);
        DateTime rs = dateTime;
        // 如果存在复杂的计算表达式
        if (lst.size() == 2) {
            String offsetExpression = lst.get(1);
            // 处理季度、月、周的第一天和最后一天
            Matcher sm = OFFSET_SPECIAL_PATTERN.matcher(offsetExpression);
            if (sm.matches()) {
                String str1 = sm.group(1);
                Preconditions.checkArgument(StringUtils.isNotBlank(str1), "unexpected expression format:%s",
                        express);
                String unit = sm.group(2);
                if (QUARTR_STRING.equalsIgnoreCase(unit)) {
                    DateTime startQuarter =
                            dateTime.plusMonths(0 - (dateTime.monthOfYear().get() - 1) % 3).dayOfMonth()
                            .withMinimumValue();
                    // 季度初
                    if (FIRST_STRING.equalsIgnoreCase(str1)) {
                        rs = startQuarter;
                    } else if (END_STRING.equalsIgnoreCase(str1)) {
                        rs = startQuarter.plusMonths(3).plusDays(-1);
                        // 季度末
                    } else {
                        throw new IllegalArgumentException(String.format("unexpected expression format:%s",
                                express));
                    }
                } else if (MONTH_STRING.equals(unit)) {
                    if (FIRST_STRING.equalsIgnoreCase(str1)) {
                        rs = dateTime.dayOfMonth().withMinimumValue();
                    } else if (END_STRING.equalsIgnoreCase(str1)) {
                        rs = dateTime.dayOfMonth().withMaximumValue();
                    } else {
                        throw new IllegalArgumentException(String.format("unexpected expression format:%s",
                                express));
                    }
                } else if (WEEK_STRING.equalsIgnoreCase(unit)) {
                    if (FIRST_STRING.equalsIgnoreCase(str1)) {
                        rs = dateTime.dayOfWeek().withMinimumValue();
                    } else if (END_STRING.equalsIgnoreCase(str1)) {
                        rs = dateTime.dayOfWeek().withMaximumValue();
                    } else {
                        throw new IllegalArgumentException(String.format("unexpected expression format:%s",
                                express));
                    }
                }
                return rs.toString(format);
            }
            // 处理一般的时间表达式
            Matcher m = OFFSET_PATTERN.matcher(offsetExpression);
            Preconditions.checkArgument(m.matches(), "unexpected expression format:%s", express);
            String numString = m.group(1);
            if (StringUtils.isBlank(numString)) {
                numString = "0";
            }
            int num = Integer.valueOf(numString).intValue();
            String unit = m.group(2);
            if (YEAR_STRING.equalsIgnoreCase(unit)) {
                // IgnoreCase
                rs = dateTime.plusYears(num);
            } else if (MONTH_STRING.equals(unit)) {
                rs = dateTime.plusMonths(num);
            } else if (WEEK_STRING.equalsIgnoreCase(unit)) {
                // IgnoreCase
                rs = dateTime.plusWeeks(num);
            } else if (DAY_STRING.equalsIgnoreCase(unit)) {
                // IgnoreCase
                rs = dateTime.plusDays(num);
            } else if (HOUR_STRING.equalsIgnoreCase(unit)) {
                // IgnoreCase
                rs = dateTime.plusHours(num);
            } else if (MINUTE_STRING.equals(unit)) {
                rs = dateTime.plusMinutes(num);
            } else {
                throw new IllegalArgumentException(String.format("unexpected expression format:%s", express));
            }
        }
        return rs.toString(format);
    }

    /**
     * <pre>
     * ======================================== start ========================================
     * <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     * <html>
     * <head>
     * &
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值