您的位置:首页 > 其它

时间定位表达式-用于时间的加、减调整

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等。

另外,该表达式是大小写不敏感的,其实现代码如下,由于逻辑简单就不解释了,大家自己看吧:

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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: