From 8d5f4dc169c32bd91c7dec62c3e8c83ec9b3a6a9 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Sun, 28 Oct 2018 19:32:38 +0000 Subject: [PATCH] initial work for DateAdd function git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1212 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../impl/expr/DefaultDateFunctions.java | 43 +++++++++++++++++++ .../impl/expr/ExpressionTokenizer.java | 3 ++ .../jackcess/impl/expr/ValueSupport.java | 20 ++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java index 4039192..fe28aa7 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java @@ -157,6 +157,49 @@ public class DefaultDateFunctions } }); + public static final Function DATEADD = registerFunc(new Func3("DateAdd") { + @Override + protected Value eval3(EvalContext ctx, + Value param1, Value param2, Value param3) { + if(param3.isNull()) { + return ValueSupport.NULL_VAL; + } + + String intv = param1.getAsString(ctx).trim(); + int val = param2.getAsLongInt(ctx); + + int result = -1; + Calendar cal = nonNullToCalendar(ctx, param3); + + // FIXME + if(intv.equalsIgnoreCase(INTV_YEAR)) { + cal.add(Calendar.YEAR, val); + } else if(intv.equalsIgnoreCase(INTV_QUARTER)) { + cal.add(Calendar.MONTH, val * 3); + } else if(intv.equalsIgnoreCase(INTV_MONTH)) { + cal.add(Calendar.MONTH, val); + } else if(intv.equalsIgnoreCase(INTV_DAY_OF_YEAR)) { + cal.add(Calendar.DAY_OF_YEAR, val); + } else if(intv.equalsIgnoreCase(INTV_DAY)) { + cal.add(Calendar.DAY_OF_YEAR, val); + } else if(intv.equalsIgnoreCase(INTV_WEEKDAY)) { + cal.add(Calendar.DAY_OF_WEEK, val); + } else if(intv.equalsIgnoreCase(INTV_WEEK)) { + cal.add(Calendar.WEEK_OF_YEAR, val); + } else if(intv.equalsIgnoreCase(INTV_HOUR)) { + cal.add(Calendar.HOUR, val); + } else if(intv.equalsIgnoreCase(INTV_MINUTE)) { + cal.add(Calendar.MINUTE, val); + } else if(intv.equalsIgnoreCase(INTV_SECOND)) { + cal.add(Calendar.SECOND, val); + } else { + throw new EvalException("Invalid interval " + intv); + } + + return ValueSupport.toValue(cal); + } + }); + public static final Function NOW = registerFunc(new Func0("Now") { @Override protected Value eval0(EvalContext ctx) { diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java index c94a609..cc0fca4 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java @@ -54,6 +54,9 @@ class ExpressionTokenizer private static final char EQUALS_CHAR = '='; // access times are based on this date (not the UTC base) + static final int BASE_DATE_YEAR = 1899; + static final int BASE_DATE_MONTH = 12; + static final int BASE_DATE_DAY = 30; private static final String BASE_DATE_PREFIX = "1899/12/30 "; private static final String BASE_DATE_FMT_PREFIX = "yyyy/M/d "; diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java index 621ed37..83f88b8 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java @@ -18,10 +18,11 @@ package com.healthmarketscience.jackcess.impl.expr; import java.math.BigDecimal; import java.text.DateFormat; +import java.util.Calendar; import java.util.Date; -import com.healthmarketscience.jackcess.expr.LocaleContext; import com.healthmarketscience.jackcess.expr.EvalException; +import com.healthmarketscience.jackcess.expr.LocaleContext; import com.healthmarketscience.jackcess.expr.Value; import com.healthmarketscience.jackcess.impl.ColumnImpl; @@ -91,6 +92,23 @@ public class ValueSupport ColumnImpl.fromDateDouble(dd, ctx.getCalendar()))); } + public static Value toValue(Calendar cal) { + boolean hasTime = ((cal.get(Calendar.HOUR) != 0) || + (cal.get(Calendar.MINUTE) != 0) || + (cal.get(Calendar.SECOND) == 0)); + + boolean hasDate = + ((cal.get(Calendar.YEAR) != ExpressionTokenizer.BASE_DATE_YEAR) || + ((cal.get(Calendar.MONTH) + 1) != ExpressionTokenizer.BASE_DATE_MONTH) || + (cal.get(Calendar.DAY_OF_MONTH) == ExpressionTokenizer.BASE_DATE_DAY)); + + Value.Type type = (hasDate ? + (hasTime ? Value.Type.DATE_TIME : Value.Type.DATE) : + Value.Type.TIME); + + return new DateTimeValue(type, cal.getTime()); + } + public static Value toValue(Value.Type type, Date d) { return new DateTimeValue(type, d); } -- 2.39.5