You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by mb...@apache.org on 2018/03/27 23:48:28 UTC

[05/12] asterixdb git commit: [NO ISSUE][RT] Add job start timestamp to the joblet context

[NO ISSUE][RT] Add job start timestamp to the joblet context

- user model changes: no
- storage format changes: no
- interface changes: yes

Details:
- add job start timestamp to the joblet context
- make CommonFunctionMapUtil extensible by products
- enhance DateTimeFormatUtils.parseDateTime() to return
  timezone information and not throw exception on invalid data
- add GregorianCalendarSystem.getDayOfYear(), getWeekOfYear()
- change sleep() to sleep first then evaluate the argument
- skip fractional trailing 0s when printing nano-duration
- fix documentation about using column aliases in GroupBy

Change-Id: I190663ec5e709584ef449f8279b1d2a5a0b099dd
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2511
Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <je...@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <ti...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/8d284433
Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/8d284433
Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/8d284433

Branch: refs/heads/master
Commit: 8d284433fc4e0e034ce2f032b256b04cb128680f
Parents: c4eb7b1
Author: Dmitry Lychagin <dm...@couchbase.com>
Authored: Mon Mar 26 16:08:06 2018 -0700
Committer: Michael Blow <mb...@apache.org>
Committed: Mon Mar 26 20:52:41 2018 -0700

----------------------------------------------------------------------
 .../asterix/runtime/ParseDurationTest.java      |   4 +-
 .../org/apache/asterix/common/api/Duration.java |  39 ++-
 .../src/main/markdown/sqlpp/3_query.md          |   5 +-
 .../lang/common/util/CommonFunctionMapUtil.java |  96 +++----
 .../om/base/temporal/DateTimeFormatUtils.java   | 266 ++++++++++++-------
 .../temporal/DurationArithmeticOperations.java  |  10 +-
 .../base/temporal/GregorianCalendarSystem.java  | 148 +++++++++--
 ...ervalStartFromDateConstructorDescriptor.java |   5 +-
 .../evaluators/functions/SleepDescriptor.java   |   3 +-
 .../AdjustDateTimeForTimeZoneDescriptor.java    |   2 +-
 .../AdjustTimeForTimeZoneDescriptor.java        |   2 +-
 .../functions/temporal/DayOfWeekDescriptor.java |  31 +--
 .../functions/temporal/ParseDateDescriptor.java |  49 ++--
 .../temporal/ParseDateTimeDescriptor.java       |  43 ++-
 .../functions/temporal/ParseTimeDescriptor.java |  43 ++-
 .../functions/temporal/PrintDateDescriptor.java |  16 +-
 .../temporal/PrintDateTimeDescriptor.java       |  14 +-
 .../functions/temporal/PrintTimeDescriptor.java |  14 +-
 .../api/context/IHyracksJobletContext.java      |   2 +
 .../control/cc/executor/JobExecutor.java        |   3 +-
 .../control/common/base/INodeController.java    |   2 +-
 .../control/common/ipc/CCNCFunctions.java       |  16 +-
 .../common/ipc/NodeControllerRemoteProxy.java   |   6 +-
 .../org/apache/hyracks/control/nc/Joblet.java   |  10 +-
 .../hyracks/control/nc/NodeControllerIPCI.java  |   2 +-
 .../hyracks/control/nc/work/StartTasksWork.java |   7 +-
 .../hyracks/test/support/TestJobletContext.java |   7 +
 27 files changed, 521 insertions(+), 324 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java
index f2fb580..d20d72d 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java
@@ -136,7 +136,7 @@ public class ParseDurationTest {
     public void testDurationFormatNanos() throws Exception {
         Assert.assertEquals("123.456789012s", Duration.formatNanos(123456789012l));
         Assert.assertEquals("12.345678901s", Duration.formatNanos(12345678901l));
-        Assert.assertEquals("1.234567890s", Duration.formatNanos(1234567890l));
+        Assert.assertEquals("1.23456789s", Duration.formatNanos(1234567890l));
         Assert.assertEquals("123.456789ms", Duration.formatNanos(123456789l));
         Assert.assertEquals("12.345678ms", Duration.formatNanos(12345678l));
         Assert.assertEquals("1.234567ms", Duration.formatNanos(1234567l));
@@ -147,7 +147,7 @@ public class ParseDurationTest {
         Assert.assertEquals("12ns", Duration.formatNanos(12l));
         Assert.assertEquals("1ns", Duration.formatNanos(1l));
         Assert.assertEquals("-123.456789012s", Duration.formatNanos(-123456789012l));
-        Assert.assertEquals("120.000000000s", Duration.formatNanos(120000000000l));
+        Assert.assertEquals("120s", Duration.formatNanos(120000000000l));
         Assert.assertEquals("-12ns", Duration.formatNanos(-12l));
     }
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java
index 4338222..a8b43b7 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java
@@ -30,6 +30,8 @@ public enum Duration {
     MICRO("µs", 3),
     NANO("ns", 0);
 
+    static final Duration[] VALUES = values();
+
     static final long NANOSECONDS = 1;
     static final long MICROSECONDS = 1000 * NANOSECONDS;
     static final long MILLISECONDS = 1000 * MICROSECONDS;
@@ -46,16 +48,29 @@ public enum Duration {
     }
 
     public static String formatNanos(long nanoTime) {
-        final String strTime = String.valueOf(nanoTime);
+        StringBuilder sb = new StringBuilder();
+        formatNanos(nanoTime, sb);
+        return sb.toString();
+    }
+
+    public static void formatNanos(long nanoTime, StringBuilder out) {
+        final String strTime = String.valueOf(Math.abs(nanoTime));
         final int len = strTime.length();
-        for (Duration tu : Duration.values()) {
-            if (len > tu.nanoDigits) {
-                final String integer = strTime.substring(0, len - tu.nanoDigits);
-                final String fractional = strTime.substring(len - tu.nanoDigits);
-                return integer + (fractional.length() > 0 ? "." + fractional : "") + tu.unit;
+        for (Duration tu : VALUES) {
+            int n = len - tu.nanoDigits;
+            if (n > 0) {
+                if (nanoTime < 0) {
+                    out.append('-');
+                }
+                out.append(strTime, 0, n);
+                int k = lastIndexOf(strTime, n, '1', '9');
+                if (k > 0) {
+                    out.append('.').append(strTime, n, k + 1);
+                }
+                out.append(tu.unit);
+                break;
             }
         }
-        return "illegal string value: " + strTime;
     }
 
     // ParseDuration parses a duration string.
@@ -233,4 +248,14 @@ public enum Duration {
         }
         return Triple.of(x, scale, s.substring(i));
     }
+
+    private static int lastIndexOf(CharSequence seq, int fromIndex, char rangeStart, char rangeEnd) {
+        for (int i = seq.length() - 1; i >= fromIndex; i--) {
+            char c = seq.charAt(i);
+            if (c >= rangeStart && c <= rangeEnd) {
+                return i;
+            }
+        }
+        return -1;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
index bcf3094..56103e5 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
@@ -1200,13 +1200,14 @@ The following is the equivalent rewritten query that will be generated by the co
     GROUP AS `$1`(msg AS msg);
 
 ### <a id="Column_aliases">Column Aliases</a>
-SQL++ also allows column aliases to be used as `GROUP BY` keys or `ORDER BY` keys.
+SQL++ also allows column aliases to be used as `ORDER BY` keys.
 
 ##### Example
 
     SELECT msg.authorId AS aid, COUNT(*)
     FROM GleambookMessages msg
-    GROUP BY aid;
+    GROUP BY msg.authorId;
+    ORDER BY aid;
 
 This query returns:
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
index 2aaf08f..3116521 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
@@ -32,66 +32,66 @@ public class CommonFunctionMapUtil {
     private static final Map<String, String> FUNCTION_NAME_MAP = new HashMap<>();
 
     static {
-        FUNCTION_NAME_MAP.put("ceil", "ceiling"); //ceil,  internal: ceiling
-        FUNCTION_NAME_MAP.put("length", "string-length"); // length,  internal: string-length
-        FUNCTION_NAME_MAP.put("lower", "lowercase"); // lower, internal: lowercase
-        FUNCTION_NAME_MAP.put("substr", "substring"); // substr,  internal: substring
-        FUNCTION_NAME_MAP.put("upper", "uppercase"); // upper, internal: uppercase
-        FUNCTION_NAME_MAP.put("title", "initcap"); // title, internal: initcap
-        FUNCTION_NAME_MAP.put("regexp_contains", "matches"); // regexp_contains, internal: matches
-        FUNCTION_NAME_MAP.put("power", "caret"); //pow, internal: caret
-        FUNCTION_NAME_MAP.put("int", "integer"); // int, internal: integer
+        addFunctionMapping("ceil", "ceiling"); //ceil,  internal: ceiling
+        addFunctionMapping("length", "string-length"); // length,  internal: string-length
+        addFunctionMapping("lower", "lowercase"); // lower, internal: lowercase
+        addFunctionMapping("substr", "substring"); // substr,  internal: substring
+        addFunctionMapping("upper", "uppercase"); // upper, internal: uppercase
+        addFunctionMapping("title", "initcap"); // title, internal: initcap
+        addFunctionMapping("regexp_contains", "matches"); // regexp_contains, internal: matches
+        addFunctionMapping("power", "caret"); //pow, internal: caret
+        addFunctionMapping("int", "integer"); // int, internal: integer
 
         // The "mapped-to" names are to be deprecated.
-        FUNCTION_NAME_MAP.put("tinyint", "int8"); // tinyint, internal: int8
-        FUNCTION_NAME_MAP.put("smallint", "int16"); // smallint, internal: int16
-        FUNCTION_NAME_MAP.put("integer", "int32"); // integer, internal: int32
-        FUNCTION_NAME_MAP.put("bigint", "int64"); // bigint, internal: int64
+        addFunctionMapping("tinyint", "int8"); // tinyint, internal: int8
+        addFunctionMapping("smallint", "int16"); // smallint, internal: int16
+        addFunctionMapping("integer", "int32"); // integer, internal: int32
+        addFunctionMapping("bigint", "int64"); // bigint, internal: int64
 
         // Type functions.
-        FUNCTION_NAME_MAP.put("isnull", "is-null"); // isnull, internal: is-null
-        FUNCTION_NAME_MAP.put("ismissing", "is-missing"); // ismissing, internal: is-missing
-        FUNCTION_NAME_MAP.put("isunknown", "is-unknown"); // isunknown, internal: is-unknown
-        FUNCTION_NAME_MAP.put("isatomic", "is-atomic"); // isatomic, internal: is-atomic
-        FUNCTION_NAME_MAP.put("isatom", "is-atomic"); // isatom, internal: is-atomic
-        FUNCTION_NAME_MAP.put("isboolean", "is-boolean"); // isboolean, internal: is-boolean
-        FUNCTION_NAME_MAP.put("isbool", "is-boolean"); // isbool, internal: is-boolean
-        FUNCTION_NAME_MAP.put("isnumber", "is-number"); // isnumber, internal: is-number
-        FUNCTION_NAME_MAP.put("isnum", "is-number"); // isnum, internal: is-number
-        FUNCTION_NAME_MAP.put("isstring", "is-string"); // isstring, internal: is-string
-        FUNCTION_NAME_MAP.put("isstr", "is-string"); // isstr, internal: is-string
-        FUNCTION_NAME_MAP.put("isarray", "is-array"); // isarray, internal: is-array
-        FUNCTION_NAME_MAP.put("isobject", "is-object"); // isobject, internal: is-object
-        FUNCTION_NAME_MAP.put("isobj", "is-object"); // isobj, internal: is-object
-        FUNCTION_NAME_MAP.put("ifmissing", "if-missing"); // ifmissing, internal: if-missing
-        FUNCTION_NAME_MAP.put("ifnull", "if-null"); // ifnull, internal: if-null
-        FUNCTION_NAME_MAP.put("ifmissingornull", "if-missing-or-null"); // ifmissingornull, internal: if-missing-or-null
-        FUNCTION_NAME_MAP.put("ifinf", "if-inf"); // ifinf, internal: if-inf
-        FUNCTION_NAME_MAP.put("ifnan", "if-nan"); // ifnan, internal: if-nan
-        FUNCTION_NAME_MAP.put("ifnanorinf", "if-nan-or-inf"); // ifnanorinf, internal: if-nan-or-inf
-        FUNCTION_NAME_MAP.put("toboolean", "to-boolean"); // toboolean, internal: to-boolean
-        FUNCTION_NAME_MAP.put("tostring", "to-string"); // tostring, internal: to-string
-        FUNCTION_NAME_MAP.put("todouble", "to-double"); // todouble, internal: to-double
-        FUNCTION_NAME_MAP.put("tobigint", "to-bigint"); // tobigint, internal: to-bigint
-        FUNCTION_NAME_MAP.put("tonumber", "to-number"); // tonumber, internal: to-number
-        FUNCTION_NAME_MAP.put("tonum", "to-number"); // tonum, internal: to-number
+        addFunctionMapping("isnull", "is-null"); // isnull, internal: is-null
+        addFunctionMapping("ismissing", "is-missing"); // ismissing, internal: is-missing
+        addFunctionMapping("isunknown", "is-unknown"); // isunknown, internal: is-unknown
+        addFunctionMapping("isatomic", "is-atomic"); // isatomic, internal: is-atomic
+        addFunctionMapping("isatom", "is-atomic"); // isatom, internal: is-atomic
+        addFunctionMapping("isboolean", "is-boolean"); // isboolean, internal: is-boolean
+        addFunctionMapping("isbool", "is-boolean"); // isbool, internal: is-boolean
+        addFunctionMapping("isnumber", "is-number"); // isnumber, internal: is-number
+        addFunctionMapping("isnum", "is-number"); // isnum, internal: is-number
+        addFunctionMapping("isstring", "is-string"); // isstring, internal: is-string
+        addFunctionMapping("isstr", "is-string"); // isstr, internal: is-string
+        addFunctionMapping("isarray", "is-array"); // isarray, internal: is-array
+        addFunctionMapping("isobject", "is-object"); // isobject, internal: is-object
+        addFunctionMapping("isobj", "is-object"); // isobj, internal: is-object
+        addFunctionMapping("ifmissing", "if-missing"); // ifmissing, internal: if-missing
+        addFunctionMapping("ifnull", "if-null"); // ifnull, internal: if-null
+        addFunctionMapping("ifmissingornull", "if-missing-or-null"); // ifmissingornull, internal: if-missing-or-null
+        addFunctionMapping("ifinf", "if-inf"); // ifinf, internal: if-inf
+        addFunctionMapping("ifnan", "if-nan"); // ifnan, internal: if-nan
+        addFunctionMapping("ifnanorinf", "if-nan-or-inf"); // ifnanorinf, internal: if-nan-or-inf
+        addFunctionMapping("toboolean", "to-boolean"); // toboolean, internal: to-boolean
+        addFunctionMapping("tostring", "to-string"); // tostring, internal: to-string
+        addFunctionMapping("todouble", "to-double"); // todouble, internal: to-double
+        addFunctionMapping("tobigint", "to-bigint"); // tobigint, internal: to-bigint
+        addFunctionMapping("tonumber", "to-number"); // tonumber, internal: to-number
+        addFunctionMapping("tonum", "to-number"); // tonum, internal: to-number
 
         // Object functions
         // record-merge, internal: object-merge
-        FUNCTION_NAME_MAP.put("record-merge", "object-merge");
+        addFunctionMapping("record-merge", "object-merge");
         // record-concat, internal: object-concat
-        FUNCTION_NAME_MAP.put("record-concat", "object-concat");
+        addFunctionMapping("record-concat", "object-concat");
         // record-get-fields, internal: object-get-fields
-        FUNCTION_NAME_MAP.put("record-get-fields", "object-get-fields");
+        addFunctionMapping("record-get-fields", "object-get-fields");
         // record-get-field-value, internal: object-get-field-value
-        FUNCTION_NAME_MAP.put("record-get-field-value", "object-get-field-value");
+        addFunctionMapping("record-get-field-value", "object-get-field-value");
         // record-add-fields, internal: object-add-fields
-        FUNCTION_NAME_MAP.put("record-add-fields", "object-add-fields");
+        addFunctionMapping("record-add-fields", "object-add-fields");
         // record-remove-fields, internal: object-remove-fields
-        FUNCTION_NAME_MAP.put("record-remove-fields", "object-remove-fields");
+        addFunctionMapping("record-remove-fields", "object-remove-fields");
 
         // Array/Mutliset functions
-        FUNCTION_NAME_MAP.put("array_length", "len");
+        addFunctionMapping("array_length", "len");
     }
 
     private CommonFunctionMapUtil() {
@@ -118,4 +118,8 @@ public class CommonFunctionMapUtil {
         FunctionSignature newFs = new FunctionSignature(fs.getNamespace(), understoreName, fs.getArity());
         return BuiltinFunctions.isBuiltinCompilerFunction(newFs, true) ? newFs : fs;
     }
+
+    public static void addFunctionMapping(String alias, String functionName) {
+        FUNCTION_NAME_MAP.put(alias, functionName);
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java
index 300d696..de98f2d 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java
@@ -20,10 +20,14 @@ package org.apache.asterix.om.base.temporal;
 
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.TimeZone;
 
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 /**
@@ -53,7 +57,7 @@ public class DateTimeFormatUtils {
 
     private static final GregorianCalendarSystem CAL = GregorianCalendarSystem.getInstance();
 
-    private static final Charset ENCODING = Charset.forName("UTF-8");
+    private static final Charset ENCODING = StandardCharsets.UTF_8;
 
     // For time
     private static final char HOUR_CHAR = 'h';
@@ -71,7 +75,6 @@ public class DateTimeFormatUtils {
     private static final int MAX_TIMEZONE_CHARS = 1;
 
     private enum DateTimeProcessState {
-        INIT,
         YEAR,
         MONTH,
         DAY,
@@ -124,13 +127,8 @@ public class DateTimeFormatUtils {
     private static final char SKIPPER_CHAR = 'O';
     private static final int MAX_SKIPPER_CHAR = 1;
 
-    private static final int MS_PER_MINUTE = 60 * 1000;
-    private static final int MS_PER_HOUR = 60 * MS_PER_MINUTE;
-
     private static final byte TO_LOWER_OFFSET = 'A' - 'a';
 
-    private static final String[] TZ_IDS = TimeZone.getAvailableIDs();
-
     private static Comparator<byte[]> byteArrayComparator = new Comparator<byte[]>() {
         @Override
         public int compare(byte[] o1, byte[] o2) {
@@ -149,33 +147,31 @@ public class DateTimeFormatUtils {
         }
     };
 
-    private static final byte[][] TIMEZONE_IDS = new byte[TZ_IDS.length][];
+    private static final byte[][] TIMEZONE_IDS;
+    private static final int[] TIMEZONE_OFFSETS;
+
     static {
-        for (int i = 0; i < TIMEZONE_IDS.length; i++) {
-            TIMEZONE_IDS[i] = TZ_IDS[i].getBytes(ENCODING);
+        String[] tzIds = TimeZone.getAvailableIDs();
+        int tzCount = tzIds.length;
+        TIMEZONE_IDS = new byte[tzCount][];
+        TIMEZONE_OFFSETS = new int[tzCount];
+
+        for (int i = 0; i < tzCount; i++) {
+            TIMEZONE_IDS[i] = tzIds[i].getBytes(ENCODING);
         }
         Arrays.sort(TIMEZONE_IDS, byteArrayComparator);
-    }
-
-    private static final int[] TIMEZONE_OFFSETS = new int[TIMEZONE_IDS.length];
-    static {
-        for (int i = 0; i < TIMEZONE_IDS.length; i++) {
+        for (int i = 0; i < tzCount; i++) {
             TIMEZONE_OFFSETS[i] = TimeZone.getTimeZone(new String(TIMEZONE_IDS[i], ENCODING)).getRawOffset();
         }
     }
 
-    private DateTimeFormatUtils() {
-    }
+    private static final DateTimeFormatUtils INSTANCE = new DateTimeFormatUtils();
 
-    private static class DateTimeFormatUtilsHolder {
-        private static final DateTimeFormatUtils INSTANCE = new DateTimeFormatUtils();
-
-        private DateTimeFormatUtilsHolder() {
-        }
+    public static DateTimeFormatUtils getInstance() {
+        return INSTANCE;
     }
 
-    public static DateTimeFormatUtils getInstance() {
-        return DateTimeFormatUtilsHolder.INSTANCE;
+    private DateTimeFormatUtils() {
     }
 
     private int parseFormatField(byte[] format, int formatStart, int formatLength, int formatPointer, char formatChar,
@@ -274,20 +270,30 @@ public class DateTimeFormatUtils {
         return b;
     }
 
-    public long parseDateTime(byte[] data, int dataStart, int dataLength, byte[] format, int formatStart,
-            int formatLength, DateTimeParseMode parseMode) throws AsterixTemporalTypeParseException {
+    public boolean parseDateTime(AMutableInt64 outChronon, byte[] data, int dataStart, int dataLength, byte[] format,
+            int formatStart, int formatLength, DateTimeParseMode parseMode, boolean raiseParseDataError)
+            throws AsterixTemporalTypeParseException {
+        return parseDateTime(outChronon, null, null, data, dataStart, dataLength, format, formatStart, formatLength,
+                parseMode, raiseParseDataError, (byte) '\0');
+    }
+
+    public boolean parseDateTime(AMutableInt64 outChronon, Mutable<Boolean> outTimeZoneExists,
+            AMutableInt32 outTimeZone, byte[] data, int dataStart, int dataLength, byte[] format, int formatStart,
+            int formatLength, DateTimeParseMode parseMode, boolean raiseParseDataError, byte altSeparatorChar)
+            throws AsterixTemporalTypeParseException {
         int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0, ms = 0, timezone = 0;
+        boolean timezoneExists = false;
 
         boolean negativeYear = false;
-        int formatCharCopies = 0;
+        int formatCharCopies;
 
         int dataStringPointer = 0, formatPointer = 0;
 
         byte separatorChar = '\0';
 
-        DateTimeProcessState processState = DateTimeProcessState.INIT;
+        DateTimeProcessState processState;
 
-        int pointerMove = 0;
+        int pointerMove;
 
         while (dataStringPointer < dataLength && formatPointer < formatLength) {
             formatCharCopies = 0;
@@ -421,8 +427,6 @@ public class DateTimeFormatUtils {
             }
 
             switch (processState) {
-                case INIT:
-                    break;
                 case YEAR:
                     if (dataStringPointer < dataLength && data[dataStart + dataStringPointer] == HYPHEN_CHAR) {
                         negativeYear = true;
@@ -435,8 +439,12 @@ public class DateTimeFormatUtils {
                     int processedFieldsCount = 0;
                     for (int i = 0; i < formatCharCopies; i++) {
                         if (data[dataStart + dataStringPointer] < '0' || data[dataStart + dataStringPointer] > '9') {
-                            throw new AsterixTemporalTypeParseException("Unexpected char for year field at "
-                                    + (dataStart + dataStringPointer) + ": " + data[dataStart + dataStringPointer]);
+                            if (raiseParseDataError) {
+                                throw new AsterixTemporalTypeParseException("Unexpected char for year field at "
+                                        + (dataStart + dataStringPointer) + ": " + data[dataStart + dataStringPointer]);
+                            } else {
+                                return false;
+                            }
                         }
                         parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer] - '0');
                         dataStringPointer++;
@@ -467,24 +475,38 @@ public class DateTimeFormatUtils {
                             month = monthNameMatch + 1;
                             dataStringPointer += 3;
                         } else {
-                            throw new AsterixTemporalTypeParseException(
-                                    "Unrecognizable month string " + (char) data[dataStart + dataStringPointer] + " "
-                                            + (char) data[dataStart + dataStringPointer + 1] + " "
-                                            + (char) data[dataStart + dataStringPointer + 2]);
+                            if (raiseParseDataError) {
+                                throw new AsterixTemporalTypeParseException(
+                                        "Unrecognizable month string " + (char) data[dataStart + dataStringPointer]
+                                                + " " + (char) data[dataStart + dataStringPointer + 1] + " "
+                                                + (char) data[dataStart + dataStringPointer + 2]);
+                            } else {
+                                return false;
+                            }
                         }
                     } else {
                         int processedMonthFieldsCount = 0;
                         for (int i = 0; i < formatCharCopies; i++) {
                             if (data[dataStart + dataStringPointer] < '0'
                                     || data[dataStart + dataStringPointer] > '9') {
-                                throw new AsterixTemporalTypeParseException("Unexpected char for month field at "
-                                        + (dataStart + dataStringPointer) + ": " + data[dataStart + dataStringPointer]);
+                                if (raiseParseDataError) {
+                                    throw new AsterixTemporalTypeParseException(
+                                            "Unexpected char for month field at " + (dataStart + dataStringPointer)
+                                                    + ": " + data[dataStart + dataStringPointer]);
+                                } else {
+                                    return false;
+                                }
                             }
                             month = month * 10 + (data[dataStart + dataStringPointer] - '0');
                             dataStringPointer++;
                             if (processedMonthFieldsCount++ > 2) {
-                                throw new AsterixTemporalTypeParseException("Unexpected char for month field at "
-                                        + (dataStart + dataStringPointer) + ": " + data[dataStart + dataStringPointer]);
+                                if (raiseParseDataError) {
+                                    throw new AsterixTemporalTypeParseException(
+                                            "Unexpected char for month field at " + (dataStart + dataStringPointer)
+                                                    + ": " + data[dataStart + dataStringPointer]);
+                                } else {
+                                    return false;
+                                }
                             }
                         }
                         // if there are more than 2 digits for the day string
@@ -507,9 +529,13 @@ public class DateTimeFormatUtils {
                     }
                     // match the weekday name
                     if (weekdayIDSearch(data, dataStart + dataStringPointer, processedWeekdayFieldsCount) < 0) {
-                        throw new AsterixTemporalTypeParseException("Unexpected string for day-of-week: "
-                                + (new String(Arrays.copyOfRange(data, dataStart + dataStringPointer,
-                                        dataStart + dataStringPointer + processedWeekdayFieldsCount))));
+                        if (raiseParseDataError) {
+                            throw new AsterixTemporalTypeParseException("Unexpected string for day-of-week: "
+                                    + new String(data, dataStart + dataStringPointer,
+                                            dataStart + dataStringPointer + processedWeekdayFieldsCount, ENCODING));
+                        } else {
+                            return false;
+                        }
                     }
                     dataStringPointer += processedWeekdayFieldsCount;
                     break;
@@ -522,15 +548,25 @@ public class DateTimeFormatUtils {
                     parsedValue = 0;
                     for (int i = 0; i < formatCharCopies; i++) {
                         if (data[dataStart + dataStringPointer] < '0' || data[dataStart + dataStringPointer] > '9') {
-                            throw new AsterixTemporalTypeParseException("Unexpected char for " + processState.name()
-                                    + " field at " + (dataStart + dataStringPointer) + ": "
-                                    + data[dataStart + dataStringPointer]);
+                            if (raiseParseDataError) {
+                                throw new AsterixTemporalTypeParseException("Unexpected char for " + processState.name()
+                                        + " field at " + (dataStart + dataStringPointer) + ": "
+                                        + data[dataStart + dataStringPointer]);
+                            } else {
+                                return false;
+                            }
+
                         }
                         parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer] - '0');
                         dataStringPointer++;
                         if (processFieldsCount++ > expectedMaxCount) {
-                            throw new AsterixTemporalTypeParseException("Unexpected char for " + processState.name()
-                                    + " field at " + dataStringPointer + ": " + data[dataStart + dataStringPointer]);
+                            if (raiseParseDataError) {
+                                throw new AsterixTemporalTypeParseException(
+                                        "Unexpected char for " + processState.name() + " field at " + dataStringPointer
+                                                + ": " + data[dataStart + dataStringPointer]);
+                            } else {
+                                return false;
+                            }
                         }
                     }
                     // if there are more than formatCharCopies digits for the hour string
@@ -581,20 +617,29 @@ public class DateTimeFormatUtils {
                         } else if (data[dataStart + dataStringPointer] == '+') {
                             dataStringPointer++;
                         } else {
-                            throw new AsterixTemporalTypeParseException(
-                                    "Incorrect timezone hour field: expecting sign + or - but got: "
-                                            + data[dataStart + dataStringPointer]);
+                            if (raiseParseDataError) {
+                                throw new AsterixTemporalTypeParseException(
+                                        "Incorrect timezone hour field: expecting sign + or - but got: "
+                                                + data[dataStart + dataStringPointer]);
+                            } else {
+                                return false;
+                            }
                         }
+                        parsedValue = 0;
                         // timezone hours
                         for (int i = 0; i < 2; i++) {
                             if (data[dataStart + dataStringPointer + i] >= '0'
                                     && data[dataStart + dataStringPointer + i] <= '9') {
-                                timezone += (data[dataStart + dataStringPointer + i] - '0') * MS_PER_HOUR;
+                                parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer + i] - '0');
                             } else {
-                                throw new AsterixTemporalTypeParseException(
-                                        "Unexpected character for timezone hour field at "
-                                                + (dataStart + dataStringPointer) + ": "
-                                                + data[dataStart + dataStringPointer]);
+                                if (raiseParseDataError) {
+                                    throw new AsterixTemporalTypeParseException(
+                                            "Unexpected character for timezone hour field at "
+                                                    + (dataStart + dataStringPointer) + ": "
+                                                    + data[dataStart + dataStringPointer]);
+                                } else {
+                                    return false;
+                                }
                             }
                         }
                         dataStringPointer += 2;
@@ -602,18 +647,25 @@ public class DateTimeFormatUtils {
                         if (data[dataStart + dataStringPointer] == ':') {
                             dataStringPointer++;
                         }
+                        timezone = (int) (parsedValue * GregorianCalendarSystem.CHRONON_OF_HOUR);
+                        parsedValue = 0;
                         // timezone minutes
                         for (int i = 0; i < 2; i++) {
                             if (data[dataStart + dataStringPointer + i] >= '0'
                                     && data[dataStart + dataStringPointer + i] <= '9') {
-                                timezone += (data[dataStart + dataStringPointer + i] - '0') * MS_PER_MINUTE;
+                                parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer + i] - '0');
                             } else {
-                                throw new AsterixTemporalTypeParseException(
-                                        "Unexpected character for timezone minute field at "
-                                                + (dataStart + dataStringPointer) + ": "
-                                                + data[dataStart + dataStringPointer]);
+                                if (raiseParseDataError) {
+                                    throw new AsterixTemporalTypeParseException(
+                                            "Unexpected character for timezone minute field at "
+                                                    + (dataStart + dataStringPointer) + ": "
+                                                    + data[dataStart + dataStringPointer]);
+                                } else {
+                                    return false;
+                                }
                             }
                         }
+                        timezone += (int) (parsedValue * GregorianCalendarSystem.CHRONON_OF_MINUTE);
                         dataStringPointer += 2;
                         if (!negativeTimeZone) {
                             timezone *= -1;
@@ -636,17 +688,26 @@ public class DateTimeFormatUtils {
                         if (searchIdx >= 0) {
                             timezone = TIMEZONE_OFFSETS[searchIdx];
                         } else {
-                            throw new AsterixTemporalTypeParseException(
-                                    "Unexpected timezone string: " + new String(Arrays.copyOfRange(data,
-                                            dataStart + dataStringPointer, dataStart + timezoneEndField)));
+                            if (raiseParseDataError) {
+                                throw new AsterixTemporalTypeParseException("Unexpected timezone string: " + new String(
+                                        data, dataStart + dataStringPointer, dataStart + timezoneEndField, ENCODING));
+                            } else {
+                                return false;
+                            }
                         }
                         dataStringPointer = timezoneEndField;
                     }
+                    timezoneExists = true;
                     break;
                 case AMPM:
                     if (dataStringPointer + 1 < dataLength) {
                         if (hour > 12 || hour <= 0) {
-                            throw new IllegalStateException("Hour " + hour + " cannot be a time for AM.");
+                            if (raiseParseDataError) {
+                                throw new AsterixTemporalTypeParseException(
+                                        "Hour " + hour + " cannot be a time for AM/PM.");
+                            } else {
+                                return false;
+                            }
                         }
                         if (byteArrayEqualToString(data, dataStart + dataStringPointer, 2, AM_BYTEARRAY)) {
                             // do nothing
@@ -656,13 +717,21 @@ public class DateTimeFormatUtils {
                                 hour = 0;
                             }
                         } else {
-                            throw new AsterixTemporalTypeParseException(
-                                    "Unexpected string for AM/PM marker " + new String(Arrays.copyOfRange(data,
-                                            dataStart + dataStringPointer, dataStart + dataStringPointer + 2)));
+                            if (raiseParseDataError) {
+                                throw new AsterixTemporalTypeParseException("Unexpected string for AM/PM marker "
+                                        + new String(data, dataStart + dataStringPointer,
+                                                dataStart + dataStringPointer + 2, ENCODING));
+                            } else {
+                                return false;
+                            }
                         }
                         dataStringPointer += 2;
                     } else {
-                        throw new AsterixTemporalTypeParseException("Cannot find valid AM/PM marker.");
+                        if (raiseParseDataError) {
+                            throw new AsterixTemporalTypeParseException("Cannot find valid AM/PM marker.");
+                        } else {
+                            return false;
+                        }
                     }
                     break;
                 case SKIPPER:
@@ -676,14 +745,16 @@ public class DateTimeFormatUtils {
                     }
                     break;
                 case SEPARATOR:
-                    if (separatorChar == '\0') {
-                        throw new AsterixTemporalTypeParseException(
-                                "Incorrect separator char in date string as " + data[dataStart + dataStringPointer]);
-                    }
                     for (int i = 0; i < formatCharCopies; i++) {
-                        if (data[dataStart + dataStringPointer] != separatorChar) {
-                            throw new AsterixTemporalTypeParseException("Expecting separator " + separatorChar
-                                    + " but got " + data[dataStart + dataStringPointer]);
+                        byte b = data[dataStart + dataStringPointer];
+                        boolean match = b == separatorChar || (altSeparatorChar != '\0' && b == altSeparatorChar);
+                        if (!match) {
+                            if (raiseParseDataError) {
+                                throw new AsterixTemporalTypeParseException(
+                                        "Expecting separator " + separatorChar + " but got " + b);
+                            } else {
+                                return false;
+                            }
                         }
                         dataStringPointer++;
                     }
@@ -695,19 +766,33 @@ public class DateTimeFormatUtils {
         }
 
         if (dataStringPointer < dataLength) {
-            throw new AsterixTemporalTypeParseException(
-                    "The given data string is not fully parsed by the given format string");
+            if (raiseParseDataError) {
+                throw new AsterixTemporalTypeParseException(
+                        "The given data string is not fully parsed by the given format string");
+            } else {
+                return false;
+            }
         }
 
         if (formatPointer < formatLength) {
-            throw new AsterixTemporalTypeParseException(
-                    "The given format string is not fully used for the given format string");
+            if (raiseParseDataError) {
+                throw new AsterixTemporalTypeParseException(
+                        "The given format string is not fully used for the given data string");
+            } else {
+                return false;
+            }
         }
 
-        if (parseMode == DateTimeParseMode.TIME_ONLY) {
-            return CAL.getChronon(hour, min, sec, ms, timezone);
+        long chronon = parseMode == DateTimeParseMode.TIME_ONLY ? CAL.getChronon(hour, min, sec, ms, timezone)
+                : CAL.getChronon(year, month, day, hour, min, sec, ms, timezone);
+        outChronon.setValue(chronon);
+        if (outTimeZoneExists != null) {
+            outTimeZoneExists.setValue(timezoneExists);
+        }
+        if (outTimeZone != null) {
+            outTimeZone.setValue(timezone);
         }
-        return CAL.getChronon(year, month, day, hour, min, sec, ms, timezone);
+        return true;
     }
 
     public void printDateTime(long chronon, int timezone, byte[] format, int formatStart, int formatLength,
@@ -720,15 +805,15 @@ public class DateTimeFormatUtils {
         int sec = CAL.getSecOfMin(chronon);
         int ms = CAL.getMillisOfSec(chronon);
 
-        int formatCharCopies = 0;
+        int formatCharCopies;
 
         int formatPointer = 0;
 
         byte separatorChar = '\0';
 
-        DateTimeProcessState processState = DateTimeProcessState.INIT;
+        DateTimeProcessState processState;
 
-        int pointerMove = 0;
+        int pointerMove;
 
         boolean usePM = false;
         if (indexOf(format, formatStart, formatLength, 'a') >= 0) {
@@ -860,8 +945,6 @@ public class DateTimeFormatUtils {
 
             try {
                 switch (processState) {
-                    case INIT:
-                        break;
                     case YEAR:
                         if (year < 0) {
                             appender.append('-');
@@ -945,12 +1028,13 @@ public class DateTimeFormatUtils {
                             appender.append('-');
                             timezone *= -1;
                         }
-                        int timezoneField = timezone / MS_PER_HOUR;
+                        int timezoneField = (int) (timezone / GregorianCalendarSystem.CHRONON_OF_HOUR);
                         if (timezoneField < 10) {
                             appender.append('0');
                         }
                         appender.append(String.valueOf(timezoneField));
-                        timezoneField = timezone % MS_PER_HOUR / MS_PER_MINUTE;
+                        timezoneField = (int) (timezone % GregorianCalendarSystem.CHRONON_OF_HOUR
+                                / GregorianCalendarSystem.CHRONON_OF_MINUTE);
                         if (timezoneField < 10) {
                             appender.append('0');
                         }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
index 2e32378..a50adc6 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
@@ -69,14 +69,14 @@ public class DurationArithmeticOperations {
         int ms = GREG_CAL.getMillisOfSec(pointChronon);
 
         // Apply the year-month duration
-        int carry = yearMonthDuration / 12;
-        month += (yearMonthDuration % 12);
+        int carry = yearMonthDuration / GregorianCalendarSystem.MONTHS_IN_A_YEAR;
+        month += (yearMonthDuration % GregorianCalendarSystem.MONTHS_IN_A_YEAR);
 
         if (month < 1) {
-            month += 12;
+            month += GregorianCalendarSystem.MONTHS_IN_A_YEAR;
             carry -= 1;
-        } else if (month > 12) {
-            month -= 12;
+        } else if (month > GregorianCalendarSystem.MONTHS_IN_A_YEAR) {
+            month -= GregorianCalendarSystem.MONTHS_IN_A_YEAR;
             carry += 1;
         }
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java
index dd711a8..ab07620 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java
@@ -64,11 +64,14 @@ public class GregorianCalendarSystem implements ICalendarSystem {
 
     public static final int[] DAYS_SINCE_MONTH_BEGIN_ORDI = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
 
+    public static final int MONTHS_IN_A_YEAR = 12;
+    public static final int DAYS_IN_A_WEEK = 7;
+
     public static final long CHRONON_OF_SECOND = 1000;
     public static final long CHRONON_OF_MINUTE = 60 * CHRONON_OF_SECOND;
     public static final long CHRONON_OF_HOUR = 60 * CHRONON_OF_MINUTE;
     public static final long CHRONON_OF_DAY = 24 * CHRONON_OF_HOUR;
-    public static final int MONTHS_IN_A_YEAR = 12;
+    public static final long CHRONON_OF_WEEK = DAYS_IN_A_WEEK * CHRONON_OF_DAY;
 
     /**
      * Minimum feasible value of each field
@@ -104,6 +107,9 @@ public class GregorianCalendarSystem implements ICalendarSystem {
      */
     private static final int DAYS_0000_TO_1970 = 719527;
 
+    // Fixed week day anchor: Thursday, 1 January 1970
+    private final static int ANCHOR_WEEKDAY = 4;
+
     private static final GregorianCalendarSystem instance = new GregorianCalendarSystem();
 
     private GregorianCalendarSystem() {
@@ -247,7 +253,7 @@ public class GregorianCalendarSystem implements ICalendarSystem {
         return chronon - timezone;
     }
 
-    public static int getChrononInDays(long chronon) {
+    public int getChrononInDays(long chronon) {
         if (chronon >= 0) {
             return (int) (chronon / CHRONON_OF_DAY);
         } else {
@@ -274,6 +280,24 @@ public class GregorianCalendarSystem implements ICalendarSystem {
      */
     public void getExtendStringRepUntilField(long chrononTime, int timezone, Appendable sbder, Fields startField,
             Fields untilField, boolean withTimezone) throws IOException {
+        getExtendStringRepUntilField(chrononTime, timezone, sbder, startField, untilField, withTimezone, 'T');
+    }
+
+    /**
+     * Get the extended string representation of the given UTC chronon time under the given time zone. Only fields
+     * before
+     * the given field index will be returned.
+     * <p/>
+     * The extended string representation is like:<br/>
+     * [-]YYYY-MM-DDThh:mm:ss.xxx[Z|[+|-]hh:mm]
+     *
+     * @param chrononTime
+     * @param timezone
+     * @param sbder
+     * @param untilField
+     */
+    public void getExtendStringRepUntilField(long chrononTime, int timezone, Appendable sbder, Fields startField,
+            Fields untilField, boolean withTimezone, char dateTimeSeparator) throws IOException {
 
         int year = getYear(chrononTime);
         int month = getMonthOfYear(chrononTime, year);
@@ -287,7 +311,7 @@ public class GregorianCalendarSystem implements ICalendarSystem {
                 }
             case MONTH:
                 if (startField != Fields.MONTH) {
-                    sbder.append("-");
+                    sbder.append('-');
                 }
                 sbder.append(String.format("%02d", month));
                 if (untilField == Fields.MONTH) {
@@ -295,7 +319,7 @@ public class GregorianCalendarSystem implements ICalendarSystem {
                 }
             case DAY:
                 if (startField != Fields.DAY) {
-                    sbder.append("-");
+                    sbder.append('-');
                 }
                 sbder.append(String.format("%02d", getDayOfMonthYear(chrononTime, year, month)));
                 if (untilField == Fields.DAY) {
@@ -303,7 +327,7 @@ public class GregorianCalendarSystem implements ICalendarSystem {
                 }
             case HOUR:
                 if (startField != Fields.HOUR) {
-                    sbder.append("T");
+                    sbder.append(dateTimeSeparator);
                 }
                 sbder.append(String.format("%02d", getHourOfDay(chrononTime)));
                 if (untilField == Fields.HOUR) {
@@ -311,7 +335,7 @@ public class GregorianCalendarSystem implements ICalendarSystem {
                 }
             case MINUTE:
                 if (startField != Fields.MINUTE) {
-                    sbder.append(":");
+                    sbder.append(':');
                 }
                 sbder.append(String.format("%02d", getMinOfHour(chrononTime)));
                 if (untilField == Fields.MINUTE) {
@@ -319,25 +343,29 @@ public class GregorianCalendarSystem implements ICalendarSystem {
                 }
             case SECOND:
                 if (startField != Fields.SECOND) {
-                    sbder.append(":");
+                    sbder.append(':');
                 }
                 sbder.append(String.format("%02d", getSecOfMin(chrononTime)));
+                if (untilField == Fields.SECOND) {
+                    break;
+                }
+            case MILLISECOND:
+                if (startField != Fields.MILLISECOND) {
+                    sbder.append('.');
+                }
                 // add millisecond as the precision fields of a second
-                sbder.append(".").append(String.format("%03d", getMillisOfSec(chrononTime)));
+                sbder.append(String.format("%03d", getMillisOfSec(chrononTime)));
                 break;
         }
 
         if (withTimezone) {
             if (timezone == 0) {
-                sbder.append("Z");
+                sbder.append('Z');
             } else {
-                int tzMin = (int) (timezone % CHRONON_OF_HOUR / CHRONON_OF_MINUTE);
-                if (tzMin < 0) {
-                    tzMin = (short) (-1 * tzMin);
-                }
+                int tzMin = (int) ((timezone % CHRONON_OF_HOUR) / CHRONON_OF_MINUTE);
                 int tzHr = (int) (timezone / CHRONON_OF_HOUR);
-                sbder.append((tzHr >= 0 ? "-" : "+")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
-                        .append(":").append(String.format("%02d", tzMin));
+                sbder.append(tzHr >= 0 ? '-' : '+').append(String.format("%02d", tzHr < 0 ? -tzHr : tzHr)).append(':')
+                        .append(String.format("%02d", tzMin < 0 ? -tzMin : tzMin));
             }
         }
     }
@@ -390,14 +418,14 @@ public class GregorianCalendarSystem implements ICalendarSystem {
 
         if (withTimezone) {
             if (timezone == 0) {
-                sbder.append("Z");
+                sbder.append('Z');
             } else {
                 int tzMin = (int) (timezone % CHRONON_OF_HOUR / CHRONON_OF_MINUTE);
                 if (tzMin < 0) {
                     tzMin = (short) (-1 * tzMin);
                 }
                 int tzHr = (int) (timezone / CHRONON_OF_HOUR);
-                sbder.append((tzHr >= 0 ? "-" : "+")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
+                sbder.append((tzHr >= 0 ? '-' : '+')).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
                         .append(String.format("%02d", tzMin));
             }
         }
@@ -434,20 +462,36 @@ public class GregorianCalendarSystem implements ICalendarSystem {
         int day = getDurationDay(milliseconds);
 
         if (!positive) {
-            sbder.append("-");
-        }
-        sbder.append("P");
-        sbder.append((year != 0) ? year + "Y" : "");
-        sbder.append((month != 0) ? month + "M" : "");
-        sbder.append((day != 0) ? day + "D" : "");
-        sbder.append((hour != 0 || minute != 0 || second != 0 || millisecond != 0) ? "T" : "");
-        sbder.append((hour != 0) ? hour + "H" : "");
-        sbder.append((minute != 0) ? minute + "M" : "");
-        sbder.append((second != 0 || millisecond != 0) ? second : "");
+            sbder.append('-');
+        }
+        sbder.append('P');
+        if (year != 0) {
+            sbder.append(year).append('Y');
+        }
+        if (month != 0) {
+            sbder.append(month).append('M');
+        }
+        if (day != 0) {
+            sbder.append(day).append('D');
+        }
+        if (hour != 0 || minute != 0 || second != 0 || millisecond != 0) {
+            sbder.append('T');
+        }
+        if (hour != 0) {
+            sbder.append(hour).append('H');
+        }
+        if (minute != 0) {
+            sbder.append(minute).append('M');
+        }
+        if (second != 0 || millisecond != 0) {
+            sbder.append(second);
+        }
         if (millisecond > 0) {
-            sbder.append("." + millisecond);
+            sbder.append('.').append(millisecond);
+        }
+        if (second != 0 || millisecond != 0) {
+            sbder.append('S');
         }
-        sbder.append((second != 0 || millisecond != 0) ? "S" : "");
     }
 
     /**
@@ -617,6 +661,32 @@ public class GregorianCalendarSystem implements ICalendarSystem {
     }
 
     /**
+     * Get the day number in the year for the input chronon time.
+     * @param millis
+     * @param year
+     * @return
+     */
+    public int getDayOfYear(long millis, int year) {
+        long dateMillis = chrononizeBeginningOfYear(year);
+        return (int) ((millis - dateMillis) / CHRONON_OF_DAY) + 1;
+    }
+
+    /**
+     * Get the week number in the year for the input chronon time.
+     * @param millis
+     * @param year
+     * @return
+     */
+    public int getWeekOfYear(long millis, int year) {
+        int doy = getDayOfYear(millis, year);
+        int week = doy / DAYS_IN_A_WEEK;
+        if (doy % DAYS_IN_A_WEEK > 0) {
+            week++;
+        }
+        return week;
+    }
+
+    /**
      * Get the hour of the day for the given chronon time.
      *
      * @param millis
@@ -692,6 +762,26 @@ public class GregorianCalendarSystem implements ICalendarSystem {
         return ms;
     }
 
+    /**
+     * Get the day of week for the given chronon time. 0 (Sunday) to 7 (Saturday)
+     *
+     * @param millis
+     * @return
+     */
+    public int getDayOfWeek(long millis) {
+        long daysSinceAnchor = getChrononInDays(millis);
+
+        // compute the weekday (0-based, and 0 = Sunday). Adjustment is needed as the anchor day is Thursday.
+        int weekday = (int) ((daysSinceAnchor + ANCHOR_WEEKDAY) % DAYS_IN_A_WEEK);
+
+        // handle the negative weekday
+        if (weekday < 0) {
+            weekday += DAYS_IN_A_WEEK;
+        }
+
+        return weekday;
+    }
+
     public int getDurationMonth(int months) {
         return (months % 12);
     }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
index 0e1942e..e2a3614 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
@@ -87,6 +87,7 @@ public class AIntervalStartFromDateConstructorDescriptor extends AbstractScalarF
                     private ISerializerDeserializer<AInterval> intervalSerde =
                             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINTERVAL);
                     private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
+                    private final GregorianCalendarSystem cal = GregorianCalendarSystem.getInstance();
 
                     @Override
                     public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
@@ -142,8 +143,8 @@ public class AIntervalStartFromDateConstructorDescriptor extends AbstractScalarF
                                         ATypeTag.SERIALIZED_DATE_TYPE_TAG, ATypeTag.SERIALIZED_STRING_TYPE_TAG);
                             }
 
-                            intervalStart = GregorianCalendarSystem.getChrononInDays(intervalStart);
-                            intervalEnd = GregorianCalendarSystem.getChrononInDays(intervalEnd);
+                            intervalStart = cal.getChrononInDays(intervalStart);
+                            intervalEnd = cal.getChrononInDays(intervalEnd);
 
                             if (intervalEnd < intervalStart) {
                                 throw new InvalidDataFormatException(getIdentifier(),

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java
index 8bced98..c2a11bb 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java
@@ -57,7 +57,6 @@ public class SleepDescriptor extends AbstractScalarFunctionDynamicDescriptor {
 
                     @Override
                     public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
-                        evalValue.evaluate(tuple, result);
                         evalTime.evaluate(tuple, argTime);
 
                         final byte[] bytes = argTime.getByteArray();
@@ -76,6 +75,8 @@ public class SleepDescriptor extends AbstractScalarFunctionDynamicDescriptor {
                                 LOGGER.log(Level.INFO, ctx.getTaskAttemptId() + " done sleeping for " + time + " ms");
                             }
                         }
+
+                        evalValue.evaluate(tuple, result);
                     }
                 };
             }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
index 6db6a46..4b326d9 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
@@ -121,7 +121,7 @@ public class AdjustDateTimeForTimeZoneDescriptor extends AbstractScalarFunctionD
                                     Fields.MILLISECOND, true);
 
                             out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
-                            utf8Writer.writeUTF8(sbder.toString(), out);
+                            utf8Writer.writeUTF8(sbder, out);
                         } catch (IOException e1) {
                             throw new HyracksDataException(e1);
                         }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
index 6e8eb19..c8dc4ce 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
@@ -119,7 +119,7 @@ public class AdjustTimeForTimeZoneDescriptor extends AbstractScalarFunctionDynam
                                     Fields.MILLISECOND, true);
 
                             out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
-                            writer.writeUTF8(sbder.toString(), out);
+                            writer.writeUTF8(sbder, out);
                         } catch (IOException e1) {
                             throw new HyracksDataException(e1);
                         }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
index 6a3e128..7bb4265 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
@@ -47,8 +47,6 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 public class DayOfWeekDescriptor extends AbstractScalarFunctionDynamicDescriptor {
     private static final long serialVersionUID = 1L;
     public final static FunctionIdentifier FID = BuiltinFunctions.DAY_OF_WEEK;
-    // Fixed week day anchor: Thursday, 1 January 1970
-    private final static int ANCHOR_WEEKDAY = 4;
 
     public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
 
@@ -73,6 +71,8 @@ public class DayOfWeekDescriptor extends AbstractScalarFunctionDynamicDescriptor
                     private IPointable argPtr = new VoidPointable();
                     private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
 
+                    private GregorianCalendarSystem cal = GregorianCalendarSystem.getInstance();
+
                     // possible returning types
                     @SuppressWarnings("unchecked")
                     private ISerializerDeserializer<AInt64> int64Serde =
@@ -87,37 +87,22 @@ public class DayOfWeekDescriptor extends AbstractScalarFunctionDynamicDescriptor
                         byte[] bytes = argPtr.getByteArray();
                         int offset = argPtr.getStartOffset();
 
-                        int daysSinceAnchor;
-                        int reminder = 0;
+                        long chronon;
                         if (bytes[offset] == ATypeTag.SERIALIZED_DATETIME_TYPE_TAG) {
-                            daysSinceAnchor = (int) (ADateTimeSerializerDeserializer.getChronon(bytes, offset + 1)
-                                    / GregorianCalendarSystem.CHRONON_OF_DAY);
-                            reminder = (int) (ADateTimeSerializerDeserializer.getChronon(bytes, offset + 1)
-                                    % GregorianCalendarSystem.CHRONON_OF_DAY);
+                            chronon = ADateTimeSerializerDeserializer.getChronon(bytes, offset + 1);
                         } else if (bytes[offset] == ATypeTag.SERIALIZED_DATE_TYPE_TAG) {
-                            daysSinceAnchor = ADateSerializerDeserializer.getChronon(bytes, offset + 1);
+                            chronon = ADateSerializerDeserializer.getChronon(bytes, offset + 1)
+                                    * GregorianCalendarSystem.CHRONON_OF_DAY;
                         } else {
                             throw new TypeMismatchException(getIdentifier(), 0, bytes[offset],
                                     ATypeTag.SERIALIZED_DATETIME_TYPE_TAG, ATypeTag.SERIALIZED_DATE_TYPE_TAG);
                         }
 
-                        // adjust the day before 1970-01-01
-                        if (daysSinceAnchor < 0 && reminder != 0) {
-                            daysSinceAnchor -= 1;
-                        }
-
-                        // compute the weekday (0-based, and 0 = Sunday). Adjustment is needed as
-                        // the anchor day is Thursday.
-                        int weekday = (daysSinceAnchor + ANCHOR_WEEKDAY) % 7;
-
-                        // handle the negative weekday
-                        if (weekday < 0) {
-                            weekday += 7;
-                        }
+                        int weekday = cal.getDayOfWeek(chronon);
 
                         // convert from 0-based to 1-based (so 7 = Sunday)
                         if (weekday == 0) {
-                            weekday = 7;
+                            weekday = GregorianCalendarSystem.DAYS_IN_A_WEEK;
                         }
 
                         aInt64.setValue(weekday);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java
index e463eed..f8d5cf7 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java
@@ -23,10 +23,10 @@ import java.io.DataOutput;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.ADate;
 import org.apache.asterix.om.base.AMutableDate;
-import org.apache.asterix.om.base.temporal.AsterixTemporalTypeParseException;
+import org.apache.asterix.om.base.AMutableInt64;
 import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
-import org.apache.asterix.om.base.temporal.GregorianCalendarSystem;
 import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
+import org.apache.asterix.om.base.temporal.GregorianCalendarSystem;
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
@@ -49,14 +49,15 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 /**
  * <b>|(bar)</b> is a special separator used to separate different formatting options.
- * Multiple format strings can be used by separating them using <b>|(bar)</b>, and the parsing will be successful only when the format string has the <b>exact</b> match with the given data string. This means that a time string like <it>08:23:12 AM</it> will not be valid for the format string <it>h:m:s</it> as there is no AM/PM format character in the format string.
+ * Multiple format strings can be used by separating them using <b>|(bar)</b>, and the parsing will be successful only
+ * when the format string has the <b>exact</b> match with the given data string.
+ * This means that a time string like <it>08:23:12 AM</it> will not be valid for the format string <it>h:m:s</it>
+ * as there is no AM/PM format character in the format string.
  */
 public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor {
     private static final long serialVersionUID = 1L;
-    public final static FunctionIdentifier FID = BuiltinFunctions.PARSE_DATE;
-    private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
-    public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
 
+    public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         @Override
         public IFunctionDescriptor createFunctionDescriptor() {
             return new ParseDateDescriptor();
@@ -72,20 +73,23 @@ public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor
             public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
                 return new IScalarEvaluator() {
 
-                    private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-                    private DataOutput out = resultStorage.getDataOutput();
-                    private IPointable argPtr0 = new VoidPointable();
-                    private IPointable argPtr1 = new VoidPointable();
-                    private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
-                    private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
+                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+                    private final DataOutput out = resultStorage.getDataOutput();
+                    private final IPointable argPtr0 = new VoidPointable();
+                    private final IPointable argPtr1 = new VoidPointable();
+                    private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+                    private final IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
 
                     @SuppressWarnings("unchecked")
-                    private ISerializerDeserializer<ADate> dateSerde =
+                    private final ISerializerDeserializer<ADate> dateSerde =
                             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADATE);
 
-                    private AMutableDate aDate = new AMutableDate(0);
+                    private final AMutableInt64 aInt64 = new AMutableInt64(0);
+                    private final AMutableDate aDate = new AMutableDate(0);
                     private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
 
+                    private final DateTimeFormatUtils util = DateTimeFormatUtils.getInstance();
+
                     @Override
                     public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
                         resultStorage.reset();
@@ -115,7 +119,6 @@ public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor
                         utf8Ptr.set(bytes1, offset1 + 1, len1 - 1);
                         int start1 = utf8Ptr.getCharStartOffset();
                         int length1 = utf8Ptr.getUTF8Length();
-                        long chronon = 0;
 
                         int formatStart = start1;
                         int formatLength;
@@ -128,19 +131,14 @@ public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor
                                     break;
                                 }
                             }
-                            try {
-                                chronon = DT_UTILS.parseDateTime(bytes0, start0, length0, bytes1, formatStart,
-                                        formatLength, DateTimeParseMode.DATE_ONLY);
-                            } catch (AsterixTemporalTypeParseException ex) {
-                                formatStart += formatLength + 1;
-                                continue;
-                            }
-                            processSuccessfully = true;
+                            processSuccessfully = util.parseDateTime(aInt64, bytes0, start0, length0, bytes1,
+                                    formatStart, formatLength, DateTimeParseMode.DATE_ONLY, false);
+                            formatStart += formatLength + 1;
                         }
                         if (!processSuccessfully) {
                             throw new InvalidDataFormatException(getIdentifier(), ATypeTag.SERIALIZED_DATE_TYPE_TAG);
                         }
-                        aDate.setValue((int) (chronon / GregorianCalendarSystem.CHRONON_OF_DAY));
+                        aDate.setValue((int) (aInt64.getLongValue() / GregorianCalendarSystem.CHRONON_OF_DAY));
                         dateSerde.serialize(aDate, out);
                         result.set(resultStorage);
                     }
@@ -155,7 +153,6 @@ public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor
      */
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.PARSE_DATE;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java
index a391529..8bb1a20 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java
@@ -23,7 +23,7 @@ import java.io.DataOutput;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.ADateTime;
 import org.apache.asterix.om.base.AMutableDateTime;
-import org.apache.asterix.om.base.temporal.AsterixTemporalTypeParseException;
+import org.apache.asterix.om.base.AMutableInt64;
 import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
 import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
 import org.apache.asterix.om.functions.BuiltinFunctions;
@@ -48,10 +48,8 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
     private static final long serialVersionUID = 1L;
-    public final static FunctionIdentifier FID = BuiltinFunctions.PARSE_DATETIME;
-    private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
-    public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
 
+    public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         @Override
         public IFunctionDescriptor createFunctionDescriptor() {
             return new ParseDateTimeDescriptor();
@@ -67,20 +65,23 @@ public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri
             public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
                 return new IScalarEvaluator() {
 
-                    private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-                    private DataOutput out = resultStorage.getDataOutput();
-                    private IPointable argPtr0 = new VoidPointable();
-                    private IPointable argPtr1 = new VoidPointable();
-                    private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
-                    private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
+                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+                    private final DataOutput out = resultStorage.getDataOutput();
+                    private final IPointable argPtr0 = new VoidPointable();
+                    private final IPointable argPtr1 = new VoidPointable();
+                    private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+                    private final IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
 
                     @SuppressWarnings("unchecked")
-                    private ISerializerDeserializer<ADateTime> datetimeSerde =
+                    private final ISerializerDeserializer<ADateTime> datetimeSerde =
                             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADATETIME);
 
-                    private AMutableDateTime aDateTime = new AMutableDateTime(0);
+                    private final AMutableInt64 aInt64 = new AMutableInt64(0);
+                    private final AMutableDateTime aDateTime = new AMutableDateTime(0);
                     private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
 
+                    private final DateTimeFormatUtils util = DateTimeFormatUtils.getInstance();
+
                     @Override
                     public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
                         resultStorage.reset();
@@ -109,7 +110,6 @@ public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri
                         utf8Ptr.set(bytes1, offset1 + 1, len1 - 1);
                         int start1 = utf8Ptr.getCharStartOffset();
                         int length1 = utf8Ptr.getUTF8Length();
-                        long chronon = 0;
 
                         int formatStart = start1;
                         int formatLength;
@@ -122,21 +122,15 @@ public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri
                                     break;
                                 }
                             }
-                            try {
-                                chronon = DT_UTILS.parseDateTime(bytes0, start0, length0, bytes1, formatStart,
-                                        formatLength, DateTimeParseMode.DATETIME);
-                            } catch (AsterixTemporalTypeParseException ex) {
-                                formatStart += formatLength + 1;
-                                continue;
-                            }
-                            processSuccessfully = true;
+                            processSuccessfully = util.parseDateTime(aInt64, bytes0, start0, length0, bytes1,
+                                    formatStart, formatLength, DateTimeParseMode.DATETIME, false);
+                            formatStart += formatLength + 1;
                         }
-
                         if (!processSuccessfully) {
                             throw new InvalidDataFormatException(getIdentifier(),
                                     ATypeTag.SERIALIZED_DATETIME_TYPE_TAG);
                         }
-                        aDateTime.setValue(chronon);
+                        aDateTime.setValue(aInt64.getLongValue());
                         datetimeSerde.serialize(aDateTime, out);
                         result.set(resultStorage);
                     }
@@ -151,7 +145,6 @@ public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri
      */
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.PARSE_DATETIME;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
index 948c779..6b9488d 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
@@ -21,9 +21,9 @@ package org.apache.asterix.runtime.evaluators.functions.temporal;
 import java.io.DataOutput;
 
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt64;
 import org.apache.asterix.om.base.AMutableTime;
 import org.apache.asterix.om.base.ATime;
-import org.apache.asterix.om.base.temporal.AsterixTemporalTypeParseException;
 import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
 import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
 import org.apache.asterix.om.functions.BuiltinFunctions;
@@ -48,11 +48,8 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
     private static final long serialVersionUID = 1L;
-    public final static FunctionIdentifier FID = BuiltinFunctions.PARSE_TIME;
-    private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
 
     public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-
         @Override
         public IFunctionDescriptor createFunctionDescriptor() {
             return new ParseTimeDescriptor();
@@ -68,20 +65,23 @@ public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor
             public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
                 return new IScalarEvaluator() {
 
-                    private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-                    private DataOutput out = resultStorage.getDataOutput();
-                    private IPointable argPtr0 = new VoidPointable();
-                    private IPointable argPtr1 = new VoidPointable();
-                    private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
-                    private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
+                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+                    private final DataOutput out = resultStorage.getDataOutput();
+                    private final IPointable argPtr0 = new VoidPointable();
+                    private final IPointable argPtr1 = new VoidPointable();
+                    private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+                    private final IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
 
                     @SuppressWarnings("unchecked")
-                    private ISerializerDeserializer<ATime> timeSerde =
+                    private final ISerializerDeserializer<ATime> timeSerde =
                             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ATIME);
 
-                    private AMutableTime aTime = new AMutableTime(0);
+                    private final AMutableInt64 aInt64 = new AMutableInt64(0);
+                    private final AMutableTime aTime = new AMutableTime(0);
                     private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
 
+                    private final DateTimeFormatUtils util = DateTimeFormatUtils.getInstance();
+
                     @Override
                     public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
                         resultStorage.reset();
@@ -110,7 +110,6 @@ public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor
                         utf8Ptr.set(bytes1, offset1 + 1, len1 - 1);
                         int start1 = utf8Ptr.getCharStartOffset();
                         int length1 = utf8Ptr.getUTF8Length();
-                        long chronon = 0;
 
                         int formatStart = start1;
                         int formatLength;
@@ -123,21 +122,14 @@ public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor
                                     break;
                                 }
                             }
-                            try {
-                                chronon = DT_UTILS.parseDateTime(bytes0, start0, length0, bytes1, formatStart,
-                                        formatLength, DateTimeParseMode.TIME_ONLY);
-                            } catch (AsterixTemporalTypeParseException ex) {
-                                formatStart += formatLength + 1;
-                                continue;
-                            }
-                            processSuccessfully = true;
+                            processSuccessfully = util.parseDateTime(aInt64, bytes0, start0, length0, bytes1,
+                                    formatStart, formatLength, DateTimeParseMode.TIME_ONLY, false);
+                            formatStart += formatLength + 1;
                         }
-
                         if (!processSuccessfully) {
                             throw new InvalidDataFormatException(getIdentifier(), ATypeTag.SERIALIZED_TIME_TYPE_TAG);
                         }
-
-                        aTime.setValue((int) chronon);
+                        aTime.setValue((int) aInt64.getLongValue());
                         timeSerde.serialize(aTime, out);
                         result.set(resultStorage);
                     }
@@ -152,7 +144,6 @@ public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor
      */
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.PARSE_TIME;
     }
-
 }