时间定位表达式-用于时间的加、减调整
2015-07-05 00:03
302 查看
在笔者开发的应用中,经常会遇到用户对数据有按照时间进行查询或监视的需求。用户对此类需求往往是希望可以输入一个已当前时间为准,向前回溯或向后延展一定时间的一个时间段。时间段可以是一天、一周、一个月,也可以是十天、一百天、十周等。为可以灵活满足此类需求,笔者写了一个专门做时间定位运算的表达式--“时间定位表达式”。其具体格式如下:
($Now|$CurrentYear|…) [(+|-) num(y|m|w|d|h|mi|s)]+
时间定位表达式分为两个部分,“($Now|$CurrentYear|…)”部分称为锚表达式,用于标定时间计算的起始点;“[(+|-) num(y|m|w|d|h|mi|s)]+”部分称为调整表达式,用于根据起始点调整计算时间。如:$Now+3m+5h
-40mi+20s。表示以当前时间为基础,在当前月的基础上在加上3个月,在当前小时的基础上加上5小时,在当前分钟的基础上减去40分钟,在当前秒的基础上加上20秒。若当前时间为2013-9-11 14:35:45,计算后的时间为:2014-1-1118:56:05。
锚表达式的定位标记除$Now外,还有$CurrentYear,$CurrentMonth,$CurrentWeek,$CurrentDay,$CurrentHour,$CurrentMinute。若当前时间为2013-9-2214:23:38,则$Now的值为2013-9-22
14:23:38;$CurrentYear的值为2013-1-1 00:00:00,即$CurrentYear定位的时间为某年的1月1日零时;$CurrentMonth的值为2013-9-100:00:00,即$CurrentMonth定位的时间为某年某月的第1天的零时;$CurrentWeek的值为2013-9-16 00:00:00;$CurrentDay的值为2013-9-22 00:00:00,即$CurrentDay定位的时间为该天的零时;$CurrentHour的值为2013-9-2214:00:00,即$CurrentHour定位的时间为该时刻的整点;$CurrentMinute的值为2013-9-2214:23:00,即$CurrentMinute定位的时间为该分钟的整点时刻。
调整表达式的调整幅度后缀。y后缀表示年,m后缀表示月,w后缀表示周,d后缀表示天,h后缀表示小时,mi后缀表示分钟,s后缀表示秒。表达式支持“+”和“-”两种运算操作。支持对某个时间单位的连加连减操作,如:$Now-12d+5d等。
另外,该表达式是大小写不敏感的,其实现代码如下,由于逻辑简单就不解释了,大家自己看吧:
($Now|$CurrentYear|…) [(+|-) num(y|m|w|d|h|mi|s)]+
时间定位表达式分为两个部分,“($Now|$CurrentYear|…)”部分称为锚表达式,用于标定时间计算的起始点;“[(+|-) num(y|m|w|d|h|mi|s)]+”部分称为调整表达式,用于根据起始点调整计算时间。如:$Now+3m+5h
-40mi+20s。表示以当前时间为基础,在当前月的基础上在加上3个月,在当前小时的基础上加上5小时,在当前分钟的基础上减去40分钟,在当前秒的基础上加上20秒。若当前时间为2013-9-11 14:35:45,计算后的时间为:2014-1-1118:56:05。
锚表达式的定位标记除$Now外,还有$CurrentYear,$CurrentMonth,$CurrentWeek,$CurrentDay,$CurrentHour,$CurrentMinute。若当前时间为2013-9-2214:23:38,则$Now的值为2013-9-22
14:23:38;$CurrentYear的值为2013-1-1 00:00:00,即$CurrentYear定位的时间为某年的1月1日零时;$CurrentMonth的值为2013-9-100:00:00,即$CurrentMonth定位的时间为某年某月的第1天的零时;$CurrentWeek的值为2013-9-16 00:00:00;$CurrentDay的值为2013-9-22 00:00:00,即$CurrentDay定位的时间为该天的零时;$CurrentHour的值为2013-9-2214:00:00,即$CurrentHour定位的时间为该时刻的整点;$CurrentMinute的值为2013-9-2214:23:00,即$CurrentMinute定位的时间为该分钟的整点时刻。
调整表达式的调整幅度后缀。y后缀表示年,m后缀表示月,w后缀表示周,d后缀表示天,h后缀表示小时,mi后缀表示分钟,s后缀表示秒。表达式支持“+”和“-”两种运算操作。支持对某个时间单位的连加连减操作,如:$Now-12d+5d等。
另外,该表达式是大小写不敏感的,其实现代码如下,由于逻辑简单就不解释了,大家自己看吧:
public class TposExpression implements Serializable { publicstatic final String CURRENT_YEAR ="$CURRENTYEAR"; publicstatic final String CURRENT_MONTH ="$CURRENTMONTH"; publicstatic final String CURRENT_WEEK ="$CURRENTWEEK"; publicstatic final String CURRENT_DAY ="$CURRENTDAY"; publicstatic final String CURRENT_HOUR ="$CURRENTHOUR"; publicstatic final String CURRENT_MINUTE ="$CURRENTMINUTE"; publicstatic final String CURRENT_POSITION ="$NOW"; public static final String[] expressionTypes =new String[] { CURRENT_YEAR,CURRENT_MONTH, CURRENT_WEEK, CURRENT_DAY, CURRENT_HOUR, CURRENT_MINUTE,CURRENT_POSITION }; public staticfinal char YEAR ='Y'; publicstatic final charMONTH = 'M'; publicstatic final charDAY = 'D'; publicstatic final charWEEK = 'W'; publicstatic final charHOUR = 'H'; publicstatic final charMINUTE = 'I';// MI publicstatic final charSECOND = 'S'; publicstatic final charPLUS = '+'; publicstatic final charMINUS = '-'; protectedint expressionTypeIndex; protected StringanchorExpression; protected StringadjustExpression; public TposExpression(String expression) { Validate.notEmpty(expression, "expression is empty!"); expression = expression.trim(); expressionTypeIndex = checkExpression(expression); splitExression(expression); } protected int checkExpression(String expression) { expression = expression.toUpperCase(); for (int i = 0; i <expressionTypes.length; i++) { if (expression.startsWith(expressionTypes[i])) { return i; } } throw new IllegalArgumentException( "Invalid expression! Should be started with '$CurrentYear'," + "'$CurrentMonth','$CurrentWeek','$CurrentDay','$CurrentHour','$CurrentMinute','$Now' "); } protected void splitExression(String expression) { anchorExpression =expressionTypes[expressionTypeIndex]; adjustExpression = expression .substring(expressionTypes[expressionTypeIndex].length()); adjustExpression =adjustExpression.toUpperCase(); } public Date getDate() { Calendar calendar = Calendar.getInstance(); anchor(calendar, expressionTypeIndex); position(calendar, adjustExpression); // offset return calendar.getTime(); } //静态方法,指定起始时间和调整表达式,直接定位时间。该起始时间可以是锚表达式支持不了的任意时间 public static Date position(Date date, String adjustExpression) { Validate.notNull(date, "date is null!"); Validate.notEmpty(adjustExpression,"adjustExpression is empty!"); adjustExpression = adjustExpression.toUpperCase(); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); position(calendar, adjustExpression); return calendar.getTime(); } protected static void position(Calendar calendar, String expression) { char operate =' ', flag = ' '; int num = -1; for (int i = 0; i < expression.length(); i++) { char ch = expression.charAt(i); if (ch ==' ') continue; if (ch ==PLUS || ch == MINUS) { operate = ch; } else if (Character.isDigit(ch)) { int j = i + 1; for (; j < expression.length(); j++) { ch = expression.charAt(j); if (!Character.isDigit(ch)) { break; } } if (j == expression.length()) { thrownew IllegalArgumentException("Invalid expression"); } String sub = expression.substring(i, j); num = Integer.valueOf(sub).intValue(); i = j - 1; } else if (ch == YEAR || ch == MONTH || ch ==DAY || ch == WEEK || ch == HOUR || ch ==SECOND) { if (ch ==MONTH) { if (i + 1 < expression.length() && expression.charAt(i + 1) ==MINUTE) { ch = MINUTE; i++; } } flag = ch; calc(calendar, operate, flag, num); operate = ' '; flag = ' '; num = -1; } } } protected static void calc(Calendar calendar, char operate, char flag, int num) { if (operate ==PLUS) { plus(calendar, flag, num); } else if (operate == MINUS) { minus(calendar, flag, num); } else { throw new IllegalArgumentException("Invalid operate!"); } } protected static void plus(Calendar calendar, char flag, int num) { switch (flag) { case YEAR: int year = calendar.get(Calendar.YEAR); year += num; calendar.set(Calendar.YEAR, year); break; case MONTH: int month = calendar.get(Calendar.MONTH); month += num; calendar.set(Calendar.MONTH, month); break; case WEEK: num *= 7; case DAY: int day = calendar.get(Calendar.DAY_OF_YEAR); day += num; calendar.set(Calendar.DAY_OF_YEAR, day); break; case HOUR: int hour = calendar.get(Calendar.HOUR_OF_DAY); hour += num; calendar.set(Calendar.HOUR_OF_DAY, hour); break; case MINUTE: int minute = calendar.get(Calendar.MINUTE); minute += num; calendar.set(Calendar.MINUTE, minute); break; case SECOND: int second = calendar.get(Calendar.SECOND); second += num; calendar.set(Calendar.SECOND, second); break; default: throw new IllegalArgumentException("Invalid flag!"); } } protected static void minus(Calendar calendar, char flag, int num) { switch (flag) { case YEAR: int year = calendar.get(Calendar.YEAR); year -= num; calendar.set(Calendar.YEAR, year); break; case MONTH: int month = calendar.get(Calendar.MONTH); month -= num; calendar.set(Calendar.MONTH, month); break; case WEEK: num *= 7; case DAY: int day = calendar.get(Calendar.DAY_OF_YEAR); day -= num; calendar.set(Calendar.DAY_OF_YEAR, day); break; case HOUR: int hour = calendar.get(Calendar.HOUR_OF_DAY); hour -= num; calendar.set(Calendar.HOUR_OF_DAY, hour); break; case MINUTE: int minute = calendar.get(Calendar.MINUTE); minute -= num; calendar.set(Calendar.MINUTE, minute); break; case SECOND: int second = calendar.get(Calendar.SECOND); second -= num; calendar.set(Calendar.SECOND, second); break; default: throw new IllegalArgumentException("Invalid flag!"); } } protected static void anchor(Calendar calendar, int expressionTypeIndex) { switch (expressionTypeIndex) { case 0: calendar.set(Calendar.MONTH, 0); case 1: calendar.set(Calendar.DAY_OF_MONTH, 1); case 3: calendar.set(Calendar.HOUR_OF_DAY, 0); case 4: calendar.set(Calendar.MINUTE, 0); case 5: calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); break; case 2: int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); if (dayOfWeek == 1) { calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - 7); } calendar.set(Calendar.DAY_OF_WEEK, 2);// Monday calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); break; } } public String getAnchorExpression() { returnanchorExpression; } public String getAdjustExpression() { returnadjustExpression; } } |
相关文章推荐
- 用Fast Sweeping Method解Eikonal Equation方程
- Get the ID of a drawable in ImageView
- 【Android】ImageView的src和background的区别以及两者的妙用
- Lua学习
- A股上证指数日变化趋势聚类分析
- LeetCode Reverse Linked List (反置链表)
- php实现短信发送代码
- PHP中$_SERVER使用说明
- PHP 获取ip地址代码汇总
- PHP版QQ互联OAuth示例代码分享
- php超快高效率统计大文件行数
- 启用Csrf后POST数据时出现的400错误
- PHP生成唯一订单号
- NFS技术实现图片共享存储
- javascript常用功能汇总
- javascript 应用小技巧方法汇总
- 浅谈angularJS 作用域
- javascript遇到html5的一些表单属性
- javascript实现控制的多级下拉菜单
- jQuery的Scrollify插件实现滑动到页面下一节点