所有
我正在处理或重写我之前写过的一些代码。该代码的目标是基于以下格式的字符串计算日期和时间:
哪一天(当地时间)开始,例如2011-09-15 00:00:00 BST(2011-09-15 23:00 GMT)然后加2小时,加1天,减去2分钟。
实现是用Java编写的,原始算法非常基础。它遍历字符串中的每个字符并附加到缓冲区。然后检查缓冲区以查看它是否以我正在查找的字符串结束(日期说明符,例如MINUTE,HOUR,DAYSTART等)然后提取数字并添加到ArrayList,其中DateOffset是一个带有int和String的简单类这是日期说明者。以下是一些示例代码:
// hard coded for sample
String s = "DayStart+2Hour+1Day-2Minutes";
StringBuilder sbBuffer = new StringBuilder();
String buffer;
// iterate through date string
for (char c : s.toCharArray()) {
sbBuffer.append(c);
buffer = sbBuffer.toString();
// check to see the end of the buffer string is what we expect
if (buffer.endsWith("DAYSTART")) {
offsets.add(new DateOffset(0, "DAYSTART"));
sbBuffer = new StringBuilder();
} else if (buffer.endsWith("DAY") && buffer.length() > 3) {
String numberStringPart = buffer.substring(0, buffer.length() - 3);
numberStringPart = numberStringPart.replaceAll("[+]", "").trim(); // need as parseInt does not like the +.
offsets.add(new DateOffset(Integer.parseInt(numberStringPart), "DAY"));
sbBuffer = new StringBuilder();
} ... and so on ...
else {
}
}
解析字符串后,我遍历ArrayList来计算我的日期时间。
虽然我们没有遇到任何问题,但上述问题可能效率不高。它也不会发现任何错误,因此您可以输入DayStart + 2GKGKER。
我只想提出一些关于用什么来重写它的新鲜而全新的想法。我做了一点正则表达式,但不太确定这是否是最好的路线。
有什么想法吗?
谢谢,
Andez
答案 0 :(得分:3)
为表达式定义语法。看一下ANTLR框架,帮助您构建语法并处理表达式。
答案 1 :(得分:1)
如果您正在进行快速实验,有时候一个识字的API与即时编辑相结合是一种简单的方法。
因此,您的示例可能看起来像(给定适当的静态导入)
daystart().plus()
.hours(2).plus()
.days(1).minutes(2)
或甚至(以毫秒为基本单位)
daystart() + hours(2) + days(1) - minutes(2)
答案 2 :(得分:1)
public class DateExpressions {
private Map<String, Date> dateVariables;
private Map<String, Integer> temporalUnits;
private Map<Character, Integer> temporalOperations;
public static DateExpressions createInstance() {
DateExpressions de = new DateExpressions();
Calendar c = Calendar.getInstance();
de.setVariable("NOW", c.getTime());
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
de.setVariable("DayStart", c.getTime());
c.set(Calendar.DAY_OF_MONTH, 1);
de.setVariable("MonthStart", c.getTime());
return de;
}
public DateExpressions() {
this.dateVariables = new HashMap<String, Date>();
this.temporalUnits = new HashMap<String, Integer>();
this.temporalUnits.put("Second", Calendar.SECOND);
this.temporalUnits.put("Minute", Calendar.MINUTE);
this.temporalUnits.put("Hour", Calendar.HOUR_OF_DAY);
this.temporalUnits.put("Day", Calendar.DATE);
this.temporalUnits.put("Month", Calendar.MONTH);
this.temporalUnits.put("Year", Calendar.YEAR);
this.temporalOperations = new HashMap<Character, Integer>();
this.temporalOperations.put('+', 1);
this.temporalOperations.put('-', -1);
}
public void setVariable(String key, Date value) {
this.dateVariables.put(key, value);
}
public Date parseExpression(String expr) throws IOException {
StringReader sr = new StringReader(expr);
String s;
int n;
char c;
int offset;
int unit;
int op = 1;
Calendar base = null;
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
while ((n = sr.read()) != -1) {
c = (char) n;
if (base == null && temporalOperations.containsKey(c)) {
s = sb2.toString();
if (!dateVariables.containsKey(s)) {
throw new IOException("Unknown variable '" + s + "' used");
}
base = Calendar.getInstance();
base.setTime(dateVariables.get(sb2.toString()));
op = temporalOperations.get(c);
sb1.setLength(0);
sb2.setLength(0);
} else if (temporalOperations.containsKey(c)) {
if (!temporalUnits.containsKey(sb2.toString())) {
throw new IOException(
"Parse error: unknown temporal unit used '"
+ sb2.toString() + "'");
}
offset = Integer.parseInt(sb1.toString());
unit = temporalUnits.get(sb2.toString());
base.add(unit, op * offset);
op = temporalOperations.get(c);
sb1.setLength(0);
sb2.setLength(0);
} else if (Character.isDigit(c)) {
sb1.append(c);
} else {
sb2.append(c);
}
}
if (!temporalUnits.containsKey(sb2.toString())) {
throw new IOException("Parse error: unknown temporal unit used '"
+ sb2.toString() + "'");
}
offset = Integer.parseInt(sb1.toString());
unit = temporalUnits.get(sb2.toString());
base.add(unit, op * offset);
return base.getTime();
}
public static void main(String[] args) throws IOException {
DateExpressions de = DateExpressions.createInstance();
System.out.println(de.parseExpression("DayStart+2Hour+1Day-2Minute"));
System.out.println(de.parseExpression("NOW+20Day"));
System.out.println(de.parseExpression("MonthStart+1Month"));
}
}
答案 3 :(得分:0)
正则表达式似乎是这种情况的最佳选择。虽然,我很困惑你为什么要以这种方式解释字符串,而不是使用复杂的API。