package de.skuzzle.polly.core.parser.ast.lang.operators; import java.util.Calendar; import de.skuzzle.polly.core.parser.Position; import de.skuzzle.polly.core.parser.ast.declarations.Namespace; import de.skuzzle.polly.core.parser.ast.declarations.types.Type; import de.skuzzle.polly.core.parser.ast.expressions.literals.DateLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.Literal; import de.skuzzle.polly.core.parser.ast.expressions.literals.TimespanLiteral; import de.skuzzle.polly.core.parser.ast.lang.BinaryOperator; import de.skuzzle.polly.core.parser.ast.visitor.ASTTraversalException; import de.skuzzle.polly.core.parser.ast.visitor.ExecutionVisitor; import de.skuzzle.polly.tools.collections.Stack; public class DateArithmetic extends BinaryOperator<DateLiteral, DateLiteral>{ public DateArithmetic(OpType id) { super(id); this.initTypes(Type.TIMESPAN, Type.DATE, Type.DATE); } @Override protected void exec(Stack<Literal> stack, Namespace ns, DateLiteral left, DateLiteral right, Position resultPos, ExecutionVisitor execVisitor) throws ASTTraversalException { switch (this.getOp()) { case SUB: // Timezone aware date subtraction // (http://user.xmission.com/~goodhill/dates/deltaDates.html) final Calendar l = Calendar.getInstance(); l.setTime(left.getValue()); final Calendar r = Calendar.getInstance(); r.setTime(right.getValue()); long endl = r.getTimeInMillis() + r.getTimeZone().getOffset(r.getTimeInMillis()); long startl = l.getTimeInMillis() + l.getTimeZone().getOffset(l.getTimeInMillis()); long seconds = (startl - endl) / 1000; stack.push(new TimespanLiteral(resultPos, (int) seconds)); break; default: this.invalidOperatorType(this.getOp()); } } }