⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crontabexpr.java

📁 短信开发用于文件交换处理转发的类模块
💻 JAVA
字号:
package com.pub.timeswan;

/**
 * CrontabExpr 的摘要说明
 *
 * 表达式:
 *        ${sch(minute[0-59],hour[0-23],day[1-31],month[1-12],weekday[1-7][sunday-saturday],year[1900-2200])}
 *
 * 参数说明:
 *        参数可以有0~6个,没有认为是无所谓;参数可以是:无所谓--*|null;具体一个值--10;具体多个值--10 20;一个范围--2-12:3。
 *
 * 举例:
 *        ${sch()}			每一分钟
 *        ${sch(30)}			每一小时的第30分钟
 *        ${sch(30,0 12)}		每天0和12时的第30分钟
 *        ${sch(30,,,,1-5)}		每周1到5的每小时的第30分钟
 */

import java.util.Calendar;
import java.util.Date;

class CrontabExpr {
    static class ValueType {
        static final int Arbitrary = 0;
        static final int Value = 1;
        static final int List = 2;
        static final int Range = 3;
    }

    static abstract class Value {
        public int _type = ValueType.Arbitrary;
        public int[] _values = null;
        public abstract int Start(); //{return 0;}

        public abstract int End(); //{return 0;}

        public abstract Calendar SetField(Calendar cal, int v);

        /**
         * 将表达式中的参数字符串解析成Value
         *
         * @param param string
         */
        public void ParseParameter(String param) {
            if (param.length() > 0 && param.charAt(0) != '*') {
                if (param.indexOf(' ') > 0) { //	list
                    String[] yy = param.split(" ");

                    _type = ValueType.List;
                    int[] vals = new int[yy.length];

                    int val;
                    int count = 0;
                    for(String y : yy) {
                        val = -1;
                        try {
                            val = Integer.parseInt(y);
                        }
                        catch(Throwable ex) {continue; }

                        if (val >= Start() && val <= End()) {
                            vals[count++] = val;
                        }
                      }

                      if (count > 0) {
                            if (count == yy.length) {
                                _values = vals;
                            } else {
                                _values = new int[count];
                                for (int i = 0; i < count; i++) {
                                    _values[i] = vals[i];
                                }
                            }
                        }
                    }
                    else if (param.indexOf('-') >= 0) { //	range:eg.1-2;1-;1-10:2;1-20:;-
                        //String[] yy = param.split("-");

                        _type = ValueType.Range;
                        _values = new int[3]; // step

                        _values[1] = param.indexOf('-');
                        _values[2] = param.indexOf(':');
                        if (_values[2] == -1) {
                            _values[2] = param.length();
                        }

                        int val = -1;
                        try {
                            val = Integer.parseInt(param.substring(0, _values[1]));
                        } catch(Throwable ex) {}

                        _values[0] = (val >= Start() && val <= End()) ? val :Start();

                        val = -1;
                        try {
                            val = Integer.parseInt(param.substring(_values[1] + 1,
                                    _values[2] /*- _values[1] - 1*/));
                        } catch(Throwable ex) {}

                        _values[1] = (val >= Start() && val <= End()) ? val : End();

                        val = -1;
                        try {
                            val = Integer.parseInt(param.substring(_values[2] + 1,
                                    param.length() /*- _values[2] - 1*/));
                        } catch(Throwable ex) {}

                         _values[2] = Math.max(1, Math.abs(val));

                    } else { // value
                        _type = ValueType.Value;
                        int val = -1;
                        boolean parseOK = true;

                        try {
                            val = Integer.parseInt(param);
                        } catch(Throwable ex) {parseOK = false; }

                        if (parseOK && val >= Start() && val <= End()) {
                            _values = new int[1];
                            _values[0] = val;
                        }
                    }
                }
            }
        }

        static class MinuteField extends Value {
            public int Start() {
                return 0;
            }

            public int End() {
                return 59;
            }

            public Calendar SetField(Calendar cal, int v) {
//                Calendar tmp = cal.getInstance();
//                tmp.setTimeInMillis(cal.getTimeInMillis());
                Calendar tmp = (Calendar)cal.clone();
                tmp.set(Calendar.MINUTE, v);
                return tmp;
            }
        }


        static class HourField extends Value {
            public int Start() {
                return 0;
            }

            public int End() {
                return 23;
            }

            public Calendar SetField(Calendar cal, int v) {
//                Calendar tmp = cal.getInstance();
//                tmp.setTimeInMillis(cal.getTimeInMillis());
//                System.out.println( new Date( cal.getTimeInMillis() ));
                Calendar tmp = (Calendar)cal.clone();
                tmp.set(Calendar.HOUR_OF_DAY, v);
//                System.out.println( new Date( tmp.getTimeInMillis() ));
                return tmp;
            }
        }


        static class DayField extends Value {
            public int Start() {
                return 0;
            }

            public int End() {
                return 31;
            }

            public Calendar SetField(Calendar cal, int v) {
//            Calendar x = t.AddMonths(1);
//            x = x.AddDays( -x.Day);
//            v = v > x.Day ? x.Day : v;
//
//            return t.AddDays(v - t.Day);

//                Calendar tmp = cal.getInstance();
//                tmp.setTimeInMillis(cal.getTimeInMillis());
                Calendar tmp = (Calendar)cal.clone();
                tmp.set(Calendar.DATE, v);
                return tmp;

            }
        }


        static class WeekdayField extends Value {
            public int Start() {
                return 0;
            }

            public int End() {
                return 6;
            }

            public Calendar SetField(Calendar cal, int v) {
//                Calendar tmp = cal.getInstance();
//                tmp.setTimeInMillis(cal.getTimeInMillis());
                Calendar tmp = (Calendar)cal.clone();
//                System.out.println( new Date( tmp.getTimeInMillis() ));
                tmp.set(Calendar.DAY_OF_WEEK, v);
//                System.out.println( new Date( tmp.getTimeInMillis() ));
                return tmp;

//            return t.AddDays(v - (int) t.DayOfWeek);
            }
        }


        static class MonthField extends Value {
            public int Start() {
                return 1;
            }

            public int End() {
                return 12;
            }

            public Calendar SetField(Calendar cal, int v) {
//            return t.AddMonths(v - t.Month);
//                Calendar tmp = cal.getInstance();
//                tmp.setTimeInMillis(cal.getTimeInMillis());
                Calendar tmp = (Calendar)cal.clone();
                tmp.set(Calendar.MONTH, v);
                return tmp;

            }
        }


        static class YearField extends Value {
            public int Start() {
                return 1900;
            }

            public int End() {
                return 2200;
            }

            public Calendar SetField(Calendar cal, int v) {
//            return t.AddYears(v - t.Year);
//                Calendar tmp = cal.getInstance();
//                tmp.setTimeInMillis(cal.getTimeInMillis());
                Calendar tmp = (Calendar)cal.clone();
                tmp.set(Calendar.YEAR, v);
                return tmp;

            }
        }


        /**
         * 解析表达式为   Calendar
         *
         * @param expr string
         *      表达式字符串
         *
         * @return Calendar
         *      解析的结果  Calendar
         */
      static String exprBegin = "${sch(";
       static public Calendar Parse(String expr) {
            Calendar now = Calendar.getInstance();

            expr = expr.toLowerCase();

            int start = expr.indexOf(exprBegin);
            //	no express,return year 0000
            if (start < 0) {
                now.setTimeInMillis(0);
                return now;
            }

            now.set(Calendar.SECOND, 0);
            now.set(Calendar.MILLISECOND, 0);

            start += exprBegin.length();
            int end = expr.indexOf(")}", start);
            //	no any parameter,return current_minute
            if (start == end) {
                return now;
            }

            String[] parms = expr.substring(start,end).split(",", 6);

            Value[] values = new Value[parms.length];

            if (parms.length >= 1 && parms[0] != null &&
                parms[0].trim().length() > 0) {
                values[0] = new MinuteField();
                values[0].ParseParameter(parms[0].trim());
            }
            if (parms.length >= 2 && parms[1] != null &&
                parms[1].trim().length() > 0) {
                values[1] = new HourField();
                values[1].ParseParameter(parms[1].trim());
            }
            if (parms.length >= 3 && parms[2] != null &&
                parms[2].trim().length() > 0) {
                values[2] = new DayField();
                values[2].ParseParameter(parms[2].trim());
            }
            if (parms.length >= 4 && parms[3] != null &&
                parms[3].trim().length() > 0) {
                values[3] = new MonthField();
                values[3].ParseParameter(parms[3].trim());
            }
            if ( /*values[2] == null && */parms.length >= 5 && parms[4] != null &&
                                          parms[4].trim().length() > 0) { // week and day conflict,so day exclude week
                values[4] = new WeekdayField();
                values[4].ParseParameter(parms[4].trim());
            }
            if (parms.length >= 6 && parms[5] != null &&
                parms[5].trim().length() > 0) {
                values[5] = new YearField();
                values[5].ParseParameter(parms[5].trim());
            }

            // combine to find lastest time
            return LastestTime(now, now, values, 0);
        }

        /**
         * 递归计算,寻找与当前时刻最接近的时刻
         * @param now Calendar
         *         当前时刻
         * @param ct Calendar
         *         计算的起点时刻
         * @param vals Value[]
         *         Value数组
         * @param start int
         *         本次处理的Value在数组中的索引
         * @return Calendar
         *         本次计算后与now最接近的时刻
         */
        static private Calendar LastestTime(Calendar now, Calendar ct, Value[] vals,int start) {
            if (start >= vals.length) {return ct;}

            Calendar ret = (Calendar)ct.clone();
            Value val = vals[start];
            //不是任意
            if (val != null && val._values != null && val._type != ValueType.Arbitrary) {
                Calendar tmp;
                double space, MaxMinuteSpace = Double.MAX_VALUE;

                if (val._type == ValueType.Value) {
                    return LastestTime(now, val.SetField(ct, val._values[0]), vals,start + 1);
                } else if (val._type == ValueType.List) {
                    for (int cur : val._values) {
                        tmp = LastestTime(now, val.SetField(ct, cur), vals,start + 1);
                        space = Math.abs(now.getTimeInMillis() - tmp.getTimeInMillis());
                        if (space < MaxMinuteSpace) {
                            MaxMinuteSpace = space;
                            ret = tmp;
                        }
                    }
                } else if (vals[start]._type == ValueType.Range) {
                    for (int cur = val._values[0]; cur <= val._values[1];
                                   cur += val._values[2]) {
                        tmp = LastestTime(now, val.SetField(ct, cur), vals,
                                          start + 1);
                        space = Math.abs(now.getTimeInMillis() - tmp.getTimeInMillis());
                        if (space < MaxMinuteSpace) {
                            MaxMinuteSpace = space;
                            ret = tmp;
                        } else {
                            break;
                        }
                    }
                }
            }
            if ((start + 1) < vals.length) {
                return LastestTime(now, ret, vals, start + 1);
            }
            return ret;
        }


        public static void main(String[] args) {
//            System.out.println(new Date( CrontabExpr.Parse("${sch()}").getTimeInMillis() ));
//            System.out.println(new Date( CrontabExpr.Parse("${sch(30)}").getTimeInMillis() ));
            System.out.println(new Date( CrontabExpr.Parse("${sch(30,18-23:3)}").getTimeInMillis() ));
//            System.out.println(new Date( CrontabExpr.Parse("${sch(30,,,,5-6)}").getTimeInMillis() ));
        }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -