]> source.dussan.org Git - jackcess.git/commitdiff
finish DateAdd function
authorJames Ahlborn <jtahlborn@yahoo.com>
Mon, 29 Oct 2018 00:55:17 +0000 (00:55 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Mon, 29 Oct 2018 00:55:17 +0000 (00:55 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1213 f203690c-595d-4dc9-a70b-905162fa7fd2

src/main/java/com/healthmarketscience/jackcess/expr/package-info.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java
src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java

index 0b58159701a6b3bb744d5d1d8099c502eee0c4dd..4db1b0d4c562e103a2692284d8aea9424e588b4a 100644 (file)
@@ -132,7 +132,7 @@ limitations under the License.
  * <tr class="TableHeadingColor" align="left"><th>Function</th><th>Supported</th></tr>
  * <tr class="TableRowColor"><td>Day</td><td>Y</td></tr>
  * <tr class="TableRowColor"><td>Date </td><td>Y</td></tr>
- * <tr class="TableRowColor"><td>DateAdd</td><td></td></tr>
+ * <tr class="TableRowColor"><td>DateAdd</td><td>Y</td></tr>
  * <tr class="TableRowColor"><td>DateDiff</td><td></td></tr>
  * <tr class="TableRowColor"><td>DatePart</td><td>Y</td></tr>
  * <tr class="TableRowColor"><td>DateSerial</td><td>Y</td></tr>
index fe28aa74e414849dcbdf430e5dfd727aedb84448..5752d58f889e69f592f75e300c04959c24e9b4d5 100644 (file)
@@ -168,10 +168,8 @@ public class DefaultDateFunctions
       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)) {
index 331a47eb47a5947e2755ef077f354faedfcacfeb..ae4d268ad7969dbec18d9213d19ff374f7968f2a 100644 (file)
@@ -17,8 +17,10 @@ limitations under the License.
 package com.healthmarketscience.jackcess.impl.expr;
 
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
 
 import com.healthmarketscience.jackcess.expr.EvalContext;
 import com.healthmarketscience.jackcess.expr.EvalException;
@@ -348,6 +350,43 @@ public class DefaultFunctions
     }
   });
 
+  // public static final Function VAL = registerStringFunc(new Func1NullIsNull("Val") {
+  //   @Override
+  //   protected Value eval1(EvalContext ctx, Value param1) {
+  //     String str = param1.getAsString(ctx).trim();
+
+  //     if(str.length() == 0) {
+  //       return ValueSupport.ZERO_VAL;
+  //     }
+
+  //     Matcher m = null;
+      
+  //     if(str.charAt(0) == ValueSupport.NUMBER_BASE_PREFIX) {
+  //       // see if we can parse as a radix format
+  //       if((m = ValueSupport.HEX_PAT.matcher(str)).find()) {
+  //         BigInteger bi = ValueSupport.parseIntegerString(m.group(), 16);
+  //         // FIXME, what to do with large numbers?  to double or decimal?
+  //         return ValueSupport.toValue(bi.intValue());
+  //       } else if((m = ValueSupport.OCTAL_PAT.matcher(str)).find()) {
+  //         BigInteger bi = ValueSupport.parseIntegerString(m.group(), 8);
+  //         // FIXME, what to do with large numbers?  to double or decimal?
+  //         return ValueSupport.toValue(bi.intValue());
+  //       }
+        
+  //       return ValueSupport.ZERO_VAL;
+  //     }
+
+  //     // parse ase normal "decimal" number.
+  //     // FIXME - leading '+'? exponent?
+  //     if((m = ValueSupport.NUMBER_PAT.matcher(str)).find()) {
+        
+  //     }
+      
+  //     // return ValueSupport.toValue(Integer.toHexString(lv).toUpperCase());
+  //     return null;
+  //   }
+  // });
+  
   private static boolean stringIsNumeric(EvalContext ctx, Value param) {
     try {
       param.getAsBigDecimal(ctx);
index 12a5efbceaf3f55283164be40bc5cf5d4c69ac00..19b22eb7e0ee6fd2d3b8833a6a9249eb529f52bd 100644 (file)
@@ -19,7 +19,6 @@ package com.healthmarketscience.jackcess.impl.expr;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.text.DecimalFormatSymbols;
-import java.util.regex.Pattern;
 
 import com.healthmarketscience.jackcess.expr.EvalException;
 import com.healthmarketscience.jackcess.expr.LocaleContext;
@@ -34,13 +33,6 @@ public class StringValue extends BaseValue
 {
   private static final Object NOT_A_NUMBER = new Object();
 
-  private static final char NUMBER_BASE_PREFIX = '&';
-  private static final Pattern OCTAL_PAT =
-    Pattern.compile(NUMBER_BASE_PREFIX + "[oO][0-7]+");
-  private static final Pattern HEX_PAT =
-    Pattern.compile(NUMBER_BASE_PREFIX + "[hH]\\p{XDigit}+");
-  private static final char CANON_DEC_SEP = '.';
-
   private final String _val;
   private Object _num;
 
@@ -119,7 +111,7 @@ public class StringValue extends BaseValue
         String tmpVal = _val.trim();
         if(tmpVal.length() > 0) {
 
-          if(tmpVal.charAt(0) != NUMBER_BASE_PREFIX) {
+          if(tmpVal.charAt(0) != ValueSupport.NUMBER_BASE_PREFIX) {
             // convert to standard numeric support for parsing
             tmpVal = toCanonicalNumberFormat(ctx, tmpVal);
             _num = ValueSupport.normalize(new BigDecimal(tmpVal));
@@ -127,9 +119,9 @@ public class StringValue extends BaseValue
           }
 
           // parse as hex/octal symbolic value
-          if(HEX_PAT.matcher(tmpVal).matches()) {
+          if(ValueSupport.HEX_PAT.matcher(tmpVal).matches()) {
             return parseIntegerString(tmpVal, 16);
-          } else if(OCTAL_PAT.matcher(tmpVal).matches()) {
+          } else if(ValueSupport.OCTAL_PAT.matcher(tmpVal).matches()) {
             return parseIntegerString(tmpVal, 8);
           }
 
@@ -144,7 +136,7 @@ public class StringValue extends BaseValue
   }
 
   private BigDecimal parseIntegerString(String tmpVal, int radix) {
-    _num = new BigDecimal(new BigInteger(tmpVal.substring(2), radix));
+    _num = new BigDecimal(ValueSupport.parseIntegerString(tmpVal, radix));
     return (BigDecimal)_num;
   }
 
@@ -158,8 +150,8 @@ public class StringValue extends BaseValue
     tmpVal = StringUtils.remove(tmpVal, groupSepChar);
 
     char decSepChar = syms.getDecimalSeparator();
-    if((decSepChar != CANON_DEC_SEP) && (tmpVal.indexOf(decSepChar) >= 0)) {
-      tmpVal = tmpVal.replace(decSepChar, CANON_DEC_SEP);
+    if((decSepChar != ValueSupport.CANON_DEC_SEP) && (tmpVal.indexOf(decSepChar) >= 0)) {
+      tmpVal = tmpVal.replace(decSepChar, ValueSupport.CANON_DEC_SEP);
     }
 
     return tmpVal;
index 83f88b8147f186f1b8df9f9333e98ce11b82559c..e2a7173042d177a382c4dc0d0cc8af655e8362fe 100644 (file)
@@ -17,9 +17,11 @@ limitations under the License.
 package com.healthmarketscience.jackcess.impl.expr;
 
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.text.DateFormat;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.regex.Pattern;
 
 import com.healthmarketscience.jackcess.expr.EvalException;
 import com.healthmarketscience.jackcess.expr.LocaleContext;
@@ -52,6 +54,14 @@ public class ValueSupport
   public static final Value NEG_ONE_VAL = TRUE_VAL;
   public static final Value ONE_VAL = new LongValue(1);
 
+  static final char NUMBER_BASE_PREFIX = '&';
+  static final Pattern OCTAL_PAT =
+    Pattern.compile("^" + NUMBER_BASE_PREFIX + "[oO][0-7]+");
+  static final Pattern HEX_PAT =
+    Pattern.compile("^" + NUMBER_BASE_PREFIX + "[hH]\\p{XDigit}+");
+  static final char CANON_DEC_SEP = '.';
+  static final Pattern NUMBER_PAT = Pattern.compile("^[-+]?[0-9]*[.]?[0-9]*");
+  
   private ValueSupport() {}
 
   public static Value toValue(boolean b) {
@@ -93,14 +103,14 @@ public class ValueSupport
   }
 
   public static Value toValue(Calendar cal) {
-    boolean hasTime = ((cal.get(Calendar.HOUR) != 0) ||
+    boolean hasTime = ((cal.get(Calendar.HOUR_OF_DAY) != 0) ||
                        (cal.get(Calendar.MINUTE) != 0) ||
-                       (cal.get(Calendar.SECOND) == 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));
+       (cal.get(Calendar.DAY_OF_MONTH) != ExpressionTokenizer.BASE_DATE_DAY));
 
     Value.Type type = (hasDate ?
                        (hasTime ? Value.Type.DATE_TIME : Value.Type.DATE) :
@@ -148,4 +158,8 @@ public class ValueSupport
     }
     return bd;
   }
+
+  static BigInteger parseIntegerString(String val, int radix) {
+    return new BigInteger(val.substring(2), radix);
+  }
 }
index c3f5f681803bc1403bb330dac1abfadf0d416f34..5f0a04592a5295bcb666ef2e4b6fbad11b471571 100644 (file)
@@ -306,6 +306,23 @@ public class DefaultFunctionsTest extends TestCase
     assertEquals(5, eval("=DatePart('h',#11/22/2003 5:45:13 AM#)"));
     assertEquals(45, eval("=DatePart('n',#11/22/2003 5:45:13 AM#)"));
     assertEquals(13, eval("=DatePart('s',#11/22/2003 5:45:13 AM#)"));
+
+    assertEquals("11/22/2005 5:45:13 AM", eval("CStr(DateAdd('yyyy',2,#11/22/2003 5:45:13 AM#))"));
+    assertEquals("2/22/2004 5:45:13 AM", eval("CStr(DateAdd('q',1,#11/22/2003 5:45:13 AM#))"));
+    assertEquals("1/22/2004 5:45:13 AM", eval("CStr(DateAdd('m',2,#11/22/2003 5:45:13 AM#))"));
+    assertEquals("12/12/2003 5:45:13 AM", eval("CStr(DateAdd('d',20,#11/22/2003 5:45:13 AM#))"));
+    assertEquals("12/12/2003 5:45:13 AM", eval("CStr(DateAdd('w',20,#11/22/2003 5:45:13 AM#))"));
+    assertEquals("12/12/2003 5:45:13 AM", eval("CStr(DateAdd('y',20,#11/22/2003 5:45:13 AM#))"));
+    assertEquals("12/27/2003 5:45:13 AM", eval("CStr(DateAdd('ww',5,#11/22/2003 5:45:13 AM#))"));
+    assertEquals("11/22/2003 3:45:13 PM", eval("CStr(DateAdd('h',10,#11/22/2003 5:45:13 AM#))"));
+    assertEquals("11/22/2003 6:19:13 AM", eval("CStr(DateAdd('n',34,#11/22/2003 5:45:13 AM#))"));
+    assertEquals("11/22/2003 5:46:27 AM", eval("CStr(DateAdd('s',74,#11/22/2003 5:45:13 AM#))"));
+
+    assertEquals("12/12/2003", eval("CStr(DateAdd('d',20,#11/22/2003#))"));
+    assertEquals("11/22/2003 10:00:00 AM", eval("CStr(DateAdd('h',10,#11/22/2003#))"));
+    assertEquals("11/23/2003", eval("CStr(DateAdd('h',24,#11/22/2003#))"));
+    assertEquals("3:45:13 PM", eval("CStr(DateAdd('h',10,#5:45:13 AM#))"));
+    assertEquals("12/31/1899 11:45:13 AM", eval("CStr(DateAdd('h',30,#5:45:13 AM#))"));
   }
 
   public void testFinancialFuncs() throws Exception