Fixed issue 54 in branch asterix_stabilization_temporal_functionality: added support for importing date, time, datetime and duration from a delimited text file. 

- original temporal type parsers are rewritten into separated IValueParsers
- added tests cases for the new importing features

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_temporal_functionality@942 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-app/data/temporal/temporalData.txt b/asterix-app/data/temporal/temporalData.txt
new file mode 100644
index 0000000..9ce94f5
--- /dev/null
+++ b/asterix-app/data/temporal/temporalData.txt
@@ -0,0 +1,4 @@
+001|-2012-12-12|23:49:12.39Z|3827-12-12T11:43:29.329|P20Y19DT3H74M23.34S
+002|1993-12-12|03:32:00|-2012-12-12T05:00:23.071|P20Y19D
+003|1839-03-12|12:30:49.382|1012-06-12T00:37:00|PT3H74M23.34S
+999|0003-11-02|23:19:32.382Z|2012-12-12T00:00:00.001|P20YT300H9.34S
diff --git a/asterix-app/src/test/resources/runtimets/queries/temp/insert_from_delimited_ds.aql b/asterix-app/src/test/resources/runtimets/queries/temp/insert_from_delimited_ds.aql
new file mode 100644
index 0000000..4520f46
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temp/insert_from_delimited_ds.aql
@@ -0,0 +1,26 @@
+/*
+ * Test case name: date-insert.aql
+ * Description: verify insertion operation for date type
+ * Expected result: success
+ */
+ 
+drop dataverse testdvt if exists;
+create dataverse testdvt;
+use dataverse testdvt;
+
+create type testtype as closed {
+  id: string,
+  dateField: date,
+  timeField: time,
+  datetimeField: datetime,
+  durationField: duration
+}
+
+write output to nc1:"rttest/temp_insert_from_delimited_ds.adm";
+
+create external dataset testds(testtype)
+using "edu.uci.ics.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="nc1://data/temporal/temporalData.txt"),("format"="delimited-text"),("delimiter"="|"));
+
+for $r in dataset("testds") 
+return {"date": $r.dateField, "time": $r.timeField, "datetime": $r.datetimeField, "duration": $r.durationField }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temp/insert_from_delimited_ds.adm b/asterix-app/src/test/resources/runtimets/results/temp/insert_from_delimited_ds.adm
new file mode 100644
index 0000000..5c40e46
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temp/insert_from_delimited_ds.adm
@@ -0,0 +1,4 @@
+{ "date": date("-2012-12-12"), "time": time("23:49:12.390Z"), "datetime": datetime("3827-12-12T11:43:29.329Z"), "duration": duration("P20Y19DT4H14M23.34S") }
+{ "date": date("1993-12-12"), "time": time("03:32:00.000Z"), "datetime": datetime("-2012-12-12T05:00:23.071Z"), "duration": duration("P20Y19D") }
+{ "date": date("1839-03-12"), "time": time("12:30:49.382Z"), "datetime": datetime("1012-06-12T00:37:00.000Z"), "duration": duration("PT4H14M23.34S") }
+{ "date": date("0003-11-02"), "time": time("23:19:32.382Z"), "datetime": datetime("2012-12-12T00:00:00.001Z"), "duration": duration("P20Y12DT12H9.34S") }
\ No newline at end of file
diff --git a/asterix-external-data/src/main/java/edu/uci/ics/asterix/external/data/parser/AbstractStreamDataParser.java b/asterix-external-data/src/main/java/edu/uci/ics/asterix/external/data/parser/AbstractStreamDataParser.java
index 403f197..98bd8e6 100644
--- a/asterix-external-data/src/main/java/edu/uci/ics/asterix/external/data/parser/AbstractStreamDataParser.java
+++ b/asterix-external-data/src/main/java/edu/uci/ics/asterix/external/data/parser/AbstractStreamDataParser.java
@@ -17,6 +17,10 @@
 import java.io.InputStream;
 import java.util.HashMap;
 
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ADateTimeParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ADurationParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.hyracks.api.comm.IFrameWriter;
@@ -33,7 +37,7 @@
 public abstract class AbstractStreamDataParser implements IDataStreamParser {
 
     public static final String KEY_DELIMITER = "delimiter";
-    
+
     protected static final HashMap<ATypeTag, IValueParserFactory> typeToValueParserFactMap = new HashMap<ATypeTag, IValueParserFactory>();
 
     static {
@@ -42,6 +46,12 @@
         typeToValueParserFactMap.put(ATypeTag.DOUBLE, DoubleParserFactory.INSTANCE);
         typeToValueParserFactMap.put(ATypeTag.INT64, LongParserFactory.INSTANCE);
         typeToValueParserFactMap.put(ATypeTag.STRING, UTF8StringParserFactory.INSTANCE);
+
+        // temporal types
+        typeToValueParserFactMap.put(ATypeTag.TIME, ATimeParserFactory.INSTANCE);
+        typeToValueParserFactMap.put(ATypeTag.DATE, ADateParserFactory.INSTANCE);
+        typeToValueParserFactMap.put(ATypeTag.DATETIME, ADateTimeParserFactory.INSTANCE);
+        typeToValueParserFactMap.put(ATypeTag.DURATION, ADurationParserFactory.INSTANCE);
     }
 
     protected ITupleParser tupleParser;
@@ -53,18 +63,16 @@
 
     @Override
     public abstract void parse(IFrameWriter frameWriter) throws HyracksDataException;
-    
+
     @Override
     public void setInputStream(InputStream in) {
         inputStream = in;
-        
+
     }
 
     @Override
     public InputStream getInputStream() {
         return inputStream;
     }
-   
-   
 
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateSerializerDeserializer.java
index 91c4587..86a9a8d 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateSerializerDeserializer.java
@@ -21,7 +21,7 @@
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.ADate;
 import edu.uci.ics.asterix.om.base.AMutableDate;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
 import edu.uci.ics.asterix.om.types.BuiltinType;
@@ -65,7 +65,7 @@
         try {
             StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
             charAccessor.reset(date, 0, date.length());
-            chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, true);
+            chrononTimeInMs = ADateParserFactory.parseDatePart(charAccessor, true);
         } catch (Exception e) {
             throw new HyracksDataException(e);
         }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateTimeSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateTimeSerializerDeserializer.java
index 4a40198..cedfc8d 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateTimeSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateTimeSerializerDeserializer.java
@@ -21,7 +21,8 @@
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.ADateTime;
 import edu.uci.ics.asterix.om.base.AMutableDateTime;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -78,11 +79,11 @@
             // if extended form 11, else 9
             timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11) : (short) (9);
 
-            chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, false);
+            chrononTimeInMs = ADateParserFactory.parseDatePart(charAccessor, false);
 
             charAccessor.reset(datetime, timeOffset, datetime.length() - timeOffset);
 
-            chrononTimeInMs += ADateAndTimeParser.parseTimePart(charAccessor);
+            chrononTimeInMs += ATimeParserFactory.parseTimePart(charAccessor);
         } catch (Exception e) {
             throw new HyracksDataException(e);
         }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADurationSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADurationSerializerDeserializer.java
index 5390abe..88e2ea5 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADurationSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADurationSerializerDeserializer.java
@@ -7,7 +7,7 @@
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.ADuration;
 import edu.uci.ics.asterix.om.base.AMutableDuration;
-import edu.uci.ics.asterix.om.base.temporal.ADurationParser;
+import edu.uci.ics.asterix.om.base.temporal.ADurationParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -49,7 +49,7 @@
             AMutableDuration aDuration = new AMutableDuration(0, 0);
             StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
             charAccessor.reset(duration, 0, duration.length());
-            ADurationParser.parse(charAccessor, aDuration);
+            ADurationParserFactory.parseDuration(charAccessor, aDuration);
 
             durationSerde.serialize(aDuration, out);
         } catch (Exception e) {
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AIntervalSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AIntervalSerializerDeserializer.java
index 61d17c1..7c87dfa 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AIntervalSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AIntervalSerializerDeserializer.java
@@ -21,7 +21,8 @@
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -118,11 +119,11 @@
             // if extended form 11, else 9
             timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11) : (short) (9);
 
-            chrononTimeInMsStart = ADateAndTimeParser.parseDatePart(charAccessor, false);
+            chrononTimeInMsStart = ADateParserFactory.parseDatePart(charAccessor, false);
 
             charAccessor.reset(interval, timeOffset, nonSpaceIndex - timeOffset + 1);
 
-            chrononTimeInMsStart += ADateAndTimeParser.parseTimePart(charAccessor);
+            chrononTimeInMsStart += ATimeParserFactory.parseTimePart(charAccessor);
 
             // Interval End
             nonSpaceIndex = commaIndex + 1;
@@ -142,11 +143,11 @@
             // if extended form 11, else 9
             timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11) : (short) (9);
 
-            chrononTimeInMsEnd = ADateAndTimeParser.parseDatePart(charAccessor, false);
+            chrononTimeInMsEnd = ADateParserFactory.parseDatePart(charAccessor, false);
 
             charAccessor.reset(interval, nonSpaceIndex + timeOffset, interval.length() - nonSpaceIndex - timeOffset);
 
-            chrononTimeInMsEnd += ADateAndTimeParser.parseTimePart(charAccessor);
+            chrononTimeInMsEnd += ATimeParserFactory.parseTimePart(charAccessor);
 
         } catch (Exception e) {
             throw new HyracksDataException(e);
@@ -179,7 +180,7 @@
 
             // Interval Start
             charAccessor.reset(interval, 0, nonSpaceIndex + 1);
-            chrononTimeInMsStart = ADateAndTimeParser.parseTimePart(charAccessor);
+            chrononTimeInMsStart = ATimeParserFactory.parseTimePart(charAccessor);
 
             if (chrononTimeInMsStart < 0) {
                 chrononTimeInMsStart += GregorianCalendarSystem.CHRONON_OF_DAY;
@@ -192,7 +193,7 @@
             }
 
             charAccessor.reset(interval, nonSpaceIndex, interval.length() - nonSpaceIndex);
-            chrononTimeInMsEnd = ADateAndTimeParser.parseTimePart(charAccessor);
+            chrononTimeInMsEnd = ATimeParserFactory.parseTimePart(charAccessor);
 
             if (chrononTimeInMsEnd < 0) {
                 chrononTimeInMsEnd += GregorianCalendarSystem.CHRONON_OF_DAY;
@@ -230,7 +231,7 @@
             // Interval Start
             charAccessor.reset(interval, 0, nonSpaceIndex + 1);
 
-            chrononTimeInMsStart = ADateAndTimeParser.parseDatePart(charAccessor, true);
+            chrononTimeInMsStart = ADateParserFactory.parseDatePart(charAccessor, true);
 
             if (chrononTimeInMsStart < 0 && chrononTimeInMsStart % GregorianCalendarSystem.CHRONON_OF_DAY != 0) {
                 tempStart = 1;
@@ -244,7 +245,7 @@
 
             charAccessor.reset(interval, nonSpaceIndex, interval.length() - nonSpaceIndex);
 
-            chrononTimeInMsEnd = ADateAndTimeParser.parseDatePart(charAccessor, true);
+            chrononTimeInMsEnd = ADateParserFactory.parseDatePart(charAccessor, true);
 
             if (chrononTimeInMsEnd < 0 && chrononTimeInMsEnd % GregorianCalendarSystem.CHRONON_OF_DAY != 0) {
                 tempEnd = 1;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ATimeSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ATimeSerializerDeserializer.java
index 92f32b8..26e8d7a 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ATimeSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ATimeSerializerDeserializer.java
@@ -7,7 +7,7 @@
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AMutableTime;
 import edu.uci.ics.asterix.om.base.ATime;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -53,7 +53,7 @@
         try {
             StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
             charAccessor.reset(time, 0, time.length());
-            chrononTimeInMs = ADateAndTimeParser.parseTimePart(charAccessor);
+            chrononTimeInMs = ATimeParserFactory.parseTimePart(charAccessor);
         } catch (Exception e) {
             throw new HyracksDataException(e);
         }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateAndTimeParser.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateAndTimeParser.java
deleted file mode 100644
index d8c4213..0000000
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateAndTimeParser.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright 2009-2011 by The Regents of the University of California
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * you may obtain a copy of the License from
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package edu.uci.ics.asterix.om.base.temporal;
-
-public class ADateAndTimeParser {
-
-    private static final GregorianCalendarSystem gCalInstance = GregorianCalendarSystem.getInstance();
-
-    private static final String dateErrorMessage = "Wrong date format!";
-    private static final String timeErrorMessage = "Wrong time format!";
-
-    /**
-     * Parse the given char sequence as a date string, and return the milliseconds represented by the date.
-     * 
-     * @param charAccessor
-     *            accessor for the char sequence
-     * @param isDateOnly
-     *            indicating whether it is a single date string, or it is the date part of a datetime string
-     * @param errorMessage
-     * @return
-     * @throws Exception
-     */
-    public static <T> long parseDatePart(ICharSequenceAccessor<T> charAccessor, boolean isDateOnly) throws Exception {
-
-        int length = charAccessor.getLength();
-        int offset = 0;
-
-        int year = 0, month = 0, day = 0;
-        boolean positive = true;
-
-        boolean isExtendedForm = false;
-
-        if (charAccessor.getCharAt(offset) == '-') {
-            offset++;
-            positive = false;
-        }
-
-        if ((isDateOnly) && charAccessor.getCharAt(offset + 4) == '-' || (!isDateOnly)
-                && charAccessor.getCharAt(offset + 13) == ':') {
-            isExtendedForm = true;
-        }
-
-        if (isExtendedForm) {
-            if (charAccessor.getCharAt(offset + 4) != '-' || charAccessor.getCharAt(offset + 7) != '-') {
-                throw new Exception("Missing dash in the date string as an extended form");
-            }
-        }
-
-        // year
-        for (int i = 0; i < 4; i++) {
-            if (charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9') {
-                year = year * 10 + charAccessor.getCharAt(offset + i) - '0';
-            } else {
-                throw new Exception("Non-numeric value in year field");
-            }
-        }
-
-        if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.YEAR.ordinal()]
-                || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.YEAR.ordinal()]) {
-            throw new Exception(dateErrorMessage + ": year " + year);
-        }
-
-        offset += (isExtendedForm) ? 5 : 4;
-
-        // month
-        for (int i = 0; i < 2; i++) {
-            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
-                month = month * 10 + charAccessor.getCharAt(offset + i) - '0';
-            } else {
-                throw new Exception("Non-numeric value in month field");
-            }
-        }
-
-        if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.MONTH.ordinal()]
-                || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.MONTH.ordinal()]) {
-            throw new Exception(dateErrorMessage + ": month " + month);
-        }
-        offset += (isExtendedForm) ? 3 : 2;
-
-        // day
-        for (int i = 0; i < 2; i++) {
-            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
-                day = day * 10 + charAccessor.getCharAt(offset + i) - '0';
-            } else {
-                throw new Exception("Non-numeric value in day field");
-            }
-        }
-
-        if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.DAY.ordinal()]
-                || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.DAY.ordinal()]) {
-            throw new Exception(dateErrorMessage + ": day " + day);
-        }
-
-        offset += 2;
-
-        if (!positive) {
-            year *= -1;
-        }
-
-        if (isDateOnly && length > offset) {
-            throw new Exception("Too many chars for a date only value");
-        }
-        return gCalInstance.getChronon(year, month, day, 0, 0, 0, 0, 0);
-    }
-
-    /**
-     * Parse the given char sequence as a time string, and return the milliseconds represented by the time.
-     * 
-     * @param charAccessor
-     * @return
-     * @throws Exception
-     */
-    public static <T> int parseTimePart(ICharSequenceAccessor<T> charAccessor) throws Exception {
-
-        int length = charAccessor.getLength();
-        int offset = 0;
-
-        int hour = 0, min = 0, sec = 0, millis = 0;
-        int timezone = 0;
-
-        boolean isExtendedForm = false;
-        if (charAccessor.getCharAt(offset + 2) == ':') {
-            isExtendedForm = true;
-        }
-
-        if (isExtendedForm && (charAccessor.getCharAt(offset + 2) != ':' || charAccessor.getCharAt(offset + 5) != ':')) {
-            throw new Exception("Missing colon in an extended time format.");
-        }
-        // hour
-        for (int i = 0; i < 2; i++) {
-            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
-                hour = hour * 10 + charAccessor.getCharAt(offset + i) - '0';
-            } else {
-                throw new Exception("Non-numeric value in hour field");
-            }
-        }
-
-        if (hour < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.HOUR.ordinal()]
-                || hour > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.HOUR.ordinal()]) {
-            throw new Exception(timeErrorMessage + ": hour " + hour);
-        }
-
-        offset += (isExtendedForm) ? 3 : 2;
-
-        // minute
-        for (int i = 0; i < 2; i++) {
-            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
-                min = min * 10 + charAccessor.getCharAt(offset + i) - '0';
-            } else {
-                throw new Exception("Non-numeric value in minute field");
-            }
-        }
-
-        if (min < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.MINUTE.ordinal()]
-                || min > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.MINUTE.ordinal()]) {
-            throw new Exception(timeErrorMessage + ": min " + min);
-        }
-
-        offset += (isExtendedForm) ? 3 : 2;
-
-        // second
-        for (int i = 0; i < 2; i++) {
-            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
-                sec = sec * 10 + charAccessor.getCharAt(offset + i) - '0';
-            } else {
-                throw new Exception("Non-numeric value in second field");
-            }
-        }
-
-        if (sec < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.SECOND.ordinal()]
-                || sec > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.SECOND.ordinal()]) {
-            throw new Exception(timeErrorMessage + ": sec " + sec);
-        }
-
-        offset += 2;
-
-        if ((isExtendedForm && length > offset && charAccessor.getCharAt(offset) == '.')
-                || (!isExtendedForm && length > offset)) {
-
-            offset += (isExtendedForm) ? 1 : 0;
-            int i = 0;
-            for (; i < 3 && offset + i < length; i++) {
-                if (charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9') {
-                    millis = millis * 10 + charAccessor.getCharAt(offset + i) - '0';
-                } else {
-                    break;
-                }
-            }
-
-            offset += i;
-
-            for (; i < 3; i++) {
-                millis = millis * 10;
-            }
-
-            // error is thrown if more than three digits are seen for the millisecond part
-            if (charAccessor.getLength() > offset && charAccessor.getCharAt(offset) >= '0'
-                    && charAccessor.getCharAt(offset) <= '9') {
-                throw new Exception("Wrong format of time instance: too many fields for millisecond.");
-            }
-        }
-
-        if (length > offset) {
-            //            if (charAccessor.getCharAt(offset) != 'Z') {
-            //                if ((charAccessor.getCharAt(offset) != '+' && charAccessor.getCharAt(offset) != '-')
-            //                        || (isExtendedForm && charAccessor.getCharAt(offset + 3) != ':')) {
-            //                    throw new Exception("Wrong timezone format: missing sign or missing colon in an extended form");
-            //                }
-            //
-            //                short timezoneHour = 0;
-            //                short timezoneMinute = 0;
-            //
-            //                for (int i = 0; i < 2; i++) {
-            //                    if ((charAccessor.getCharAt(offset + 1 + i) >= '0' && charAccessor.getCharAt(offset + 1 + i) <= '9')) {
-            //                        timezoneHour = (short) (timezoneHour * 10 + charAccessor.getCharAt(offset + 1 + i) - '0');
-            //                    } else {
-            //                        throw new Exception("Non-numeric value in timezone hour field");
-            //                    }
-            //                }
-            //
-            //                if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-            //                        || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-            //                    throw new Exception(timeErrorMessage + ": time zone hour " + timezoneHour);
-            //                }
-            //
-            //                int temp_offset = (isExtendedForm) ? 1 : 0;
-            //
-            //                for (int i = 0; i < 2; i++) {
-            //                    if ((charAccessor.getCharAt(offset + temp_offset + 3 + i) >= '0' && charAccessor.getCharAt(offset
-            //                            + temp_offset + 3 + i) <= '9')) {
-            //                        timezoneMinute = (short) (timezoneMinute * 10
-            //                                + charAccessor.getCharAt(offset + temp_offset + 3 + i) - '0');
-            //                    } else {
-            //                        throw new Exception("Non-numeric value in timezone minute field");
-            //                    }
-            //                }
-            //
-            //                if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-            //                        || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-            //                    throw new Exception(timeErrorMessage + ": time zone minute " + timezoneMinute);
-            //                }
-            //
-            //                if (charAccessor.getCharAt(offset) == '-') {
-            //                    timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-            //                } else {
-            //                    timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-            //                }
-            //            }
-            timezone = parseTimezonePart(charAccessor, offset);
-        }
-
-        return gCalInstance.getChronon(hour, min, sec, millis, timezone);
-    }
-
-    /**
-     * Parse the given char sequence as a time string, and return the milliseconds represented by the time.
-     * 
-     * @param charAccessor
-     * @return
-     * @throws Exception
-     */
-    public static <T> int parseTimezonePart(ICharSequenceAccessor<T> charAccessor, int offset) throws Exception {
-        int timezone = 0;
-
-        if (charAccessor.getCharAt(offset) != 'Z') {
-            if ((charAccessor.getCharAt(offset) != '+' && charAccessor.getCharAt(offset) != '-')) {
-                throw new Exception("Wrong timezone format: missing sign or missing colon for a time zone");
-            }
-
-            short timezoneHour = 0;
-            short timezoneMinute = 0;
-
-            for (int i = 0; i < 2; i++) {
-                if ((charAccessor.getCharAt(offset + 1 + i) >= '0' && charAccessor.getCharAt(offset + 1 + i) <= '9')) {
-                    timezoneHour = (short) (timezoneHour * 10 + charAccessor.getCharAt(offset + 1 + i) - '0');
-                } else {
-                    throw new Exception("Non-numeric value in timezone hour field");
-                }
-            }
-
-            if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-                    || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-                throw new Exception(timeErrorMessage + ": time zone hour " + timezoneHour);
-            }
-
-            int temp_offset = (charAccessor.getCharAt(offset + 3) == ':') ? 1 : 0;
-
-            for (int i = 0; i < 2; i++) {
-                if ((charAccessor.getCharAt(offset + temp_offset + 3 + i) >= '0' && charAccessor.getCharAt(offset
-                        + temp_offset + 3 + i) <= '9')) {
-                    timezoneMinute = (short) (timezoneMinute * 10
-                            + charAccessor.getCharAt(offset + temp_offset + 3 + i) - '0');
-                } else {
-                    throw new Exception("Non-numeric value in timezone minute field");
-                }
-            }
-
-            if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-                    || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-                throw new Exception(timeErrorMessage + ": time zone minute " + timezoneMinute);
-            }
-
-            if (charAccessor.getCharAt(offset) == '-') {
-                timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-            } else {
-                timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-            }
-        }
-        return timezone;
-    }
-}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateParserFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateParserFactory.java
new file mode 100644
index 0000000..8192919
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateParserFactory.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.base.temporal;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+
+public class ADateParserFactory implements IValueParserFactory {
+
+    public static final IValueParserFactory INSTANCE = new ADateParserFactory();
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String dateErrorMessage = "Wrong input format for a date value";
+
+    private ADateParserFactory() {
+
+    }
+
+    @Override
+    public IValueParser createValueParser() {
+
+        final CharArrayCharSequenceAccessor charArrayAccessor = new CharArrayCharSequenceAccessor();
+
+        return new IValueParser() {
+
+            @Override
+            public void parse(char[] buffer, int start, int length, DataOutput out) throws HyracksDataException {
+                charArrayAccessor.reset(buffer, start, length);
+                try {
+                    out.writeInt((int) (parseDatePart(charArrayAccessor, true) / GregorianCalendarSystem.CHRONON_OF_DAY));
+                } catch (IOException ex) {
+                    throw new HyracksDataException(ex);
+                }
+            }
+        };
+    }
+
+    /**
+     * Parse the given char sequence as a date string, and return the milliseconds represented by the date.
+     * 
+     * @param charAccessor
+     *            accessor for the char sequence
+     * @param isDateOnly
+     *            indicating whether it is a single date string, or it is the date part of a datetime string
+     * @param errorMessage
+     * @return
+     * @throws Exception
+     */
+    public static <T> long parseDatePart(ICharSequenceAccessor<T> charAccessor, boolean isDateOnly)
+            throws HyracksDataException {
+
+        int length = charAccessor.getLength();
+        int offset = 0;
+
+        int year = 0, month = 0, day = 0;
+        boolean positive = true;
+
+        boolean isExtendedForm = false;
+
+        if (charAccessor.getCharAt(offset) == '-') {
+            offset++;
+            positive = false;
+        }
+
+        if ((isDateOnly) && charAccessor.getCharAt(offset + 4) == '-' || (!isDateOnly)
+                && charAccessor.getCharAt(offset + 13) == ':') {
+            isExtendedForm = true;
+        }
+
+        if (isExtendedForm) {
+            if (charAccessor.getCharAt(offset + 4) != '-' || charAccessor.getCharAt(offset + 7) != '-') {
+                throw new HyracksDataException("Missing dash in the date string as an extended form");
+            }
+        }
+
+        // year
+        for (int i = 0; i < 4; i++) {
+            if (charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9') {
+                year = year * 10 + charAccessor.getCharAt(offset + i) - '0';
+            } else {
+                throw new HyracksDataException("Non-numeric value in year field");
+            }
+        }
+
+        if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.YEAR.ordinal()]
+                || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.YEAR.ordinal()]) {
+            throw new HyracksDataException(dateErrorMessage + ": year " + year);
+        }
+
+        offset += (isExtendedForm) ? 5 : 4;
+
+        // month
+        for (int i = 0; i < 2; i++) {
+            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+                month = month * 10 + charAccessor.getCharAt(offset + i) - '0';
+            } else {
+                throw new HyracksDataException("Non-numeric value in month field");
+            }
+        }
+
+        if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.MONTH.ordinal()]
+                || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.MONTH.ordinal()]) {
+            throw new HyracksDataException(dateErrorMessage + ": month " + month);
+        }
+        offset += (isExtendedForm) ? 3 : 2;
+
+        // day
+        for (int i = 0; i < 2; i++) {
+            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+                day = day * 10 + charAccessor.getCharAt(offset + i) - '0';
+            } else {
+                throw new HyracksDataException("Non-numeric value in day field");
+            }
+        }
+
+        if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.DAY.ordinal()]
+                || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.DAY.ordinal()]) {
+            throw new HyracksDataException(dateErrorMessage + ": day " + day);
+        }
+
+        offset += 2;
+
+        if (!positive) {
+            year *= -1;
+        }
+
+        if (isDateOnly && length > offset) {
+            throw new HyracksDataException("Too many chars for a date only value");
+        }
+        return GregorianCalendarSystem.getInstance().getChronon(year, month, day, 0, 0, 0, 0, 0);
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateTimeParserFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateTimeParserFactory.java
new file mode 100644
index 0000000..2df3c3b
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateTimeParserFactory.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.base.temporal;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+
+public class ADateTimeParserFactory implements IValueParserFactory {
+
+    public static final IValueParserFactory INSTANCE = new ADateTimeParserFactory();
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String dateTimeErrorMessage = "Wrong Input Format for a DateTime Value";
+
+    private ADateTimeParserFactory() {
+
+    }
+
+    @Override
+    public IValueParser createValueParser() {
+
+        final CharArrayCharSequenceAccessor charArrayAccessor = new CharArrayCharSequenceAccessor();
+
+        return new IValueParser() {
+
+            @Override
+            public void parse(char[] buffer, int start, int length, DataOutput out) throws HyracksDataException {
+                long chrononTimeInMs = 0;
+
+                charArrayAccessor.reset(buffer, start, length);
+
+                short timeOffset = (short) ((charArrayAccessor.getCharAt(0) == '-') ? 1 : 0);
+
+                if (charArrayAccessor.getCharAt(timeOffset + 10) != 'T'
+                        && charArrayAccessor.getCharAt(timeOffset + 8) != 'T') {
+                    throw new HyracksDataException(dateTimeErrorMessage + ": missing T");
+                }
+
+                // if extended form 11, else 9
+                timeOffset += (charArrayAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11) : (short) (9);
+
+                chrononTimeInMs = ADateParserFactory.parseDatePart(charArrayAccessor, false);
+
+                charArrayAccessor.reset(buffer, start + timeOffset, length - timeOffset);
+
+                chrononTimeInMs += ATimeParserFactory.parseTimePart(charArrayAccessor);
+
+                try {
+                    out.writeLong(chrononTimeInMs);
+                } catch (IOException ex) {
+                    throw new HyracksDataException(ex);
+                }
+            }
+        };
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParser.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParserFactory.java
similarity index 62%
rename from asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParser.java
rename to asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParserFactory.java
index 5d43bba..b176061 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParser.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParserFactory.java
@@ -14,9 +14,45 @@
  */
 package edu.uci.ics.asterix.om.base.temporal;
 
-import edu.uci.ics.asterix.om.base.AMutableDuration;
+import java.io.DataOutput;
+import java.io.IOException;
 
-public class ADurationParser {
+import edu.uci.ics.asterix.om.base.AMutableDuration;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+
+public class ADurationParserFactory implements IValueParserFactory {
+
+    public static final IValueParserFactory INSTANCE = new ADurationParserFactory();
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String durationErrorMessage = "Wrong Input Format for a Duration Value";
+
+    private ADurationParserFactory() {
+
+    }
+
+    @Override
+    public IValueParser createValueParser() {
+        final CharArrayCharSequenceAccessor charArrayAccessor = new CharArrayCharSequenceAccessor();
+        final AMutableDuration aMutableDuration = new AMutableDuration(0, 0);
+        return new IValueParser() {
+
+            @Override
+            public void parse(char[] buffer, int start, int length, DataOutput out) throws HyracksDataException {
+                charArrayAccessor.reset(buffer, start, length);
+                parseDuration(charArrayAccessor, aMutableDuration);
+                try {
+                    out.writeInt(aMutableDuration.getMonths());
+                    out.writeLong(aMutableDuration.getMilliseconds());
+                } catch (IOException ex) {
+                    throw new HyracksDataException(ex);
+                }
+            }
+        };
+    }
 
     private enum State {
         NOTHING_READ,
@@ -30,9 +66,8 @@
         SEC;
     };
 
-    private static final String errorMessage = "This can not be an instance of duration";
-
-    public static <T> void parse(ICharSequenceAccessor<T> charAccessor, AMutableDuration aDuration) throws Exception {
+    public static <T> void parseDuration(ICharSequenceAccessor<T> charAccessor, AMutableDuration aDuration)
+            throws HyracksDataException {
 
         boolean positive = true;
         int offset = 0;
@@ -45,7 +80,7 @@
         }
 
         if (charAccessor.getCharAt(offset++) != 'P') {
-            throw new Exception(errorMessage);
+            throw new HyracksDataException(durationErrorMessage + ": Missing leading 'P'.");
         }
 
         for (; offset < charAccessor.getLength(); offset++) {
@@ -59,7 +94,7 @@
                             year = value;
                             state = State.YEAR;
                         } else {
-                            throw new Exception(errorMessage);
+                            throw new HyracksDataException(durationErrorMessage + ": wrong YEAR feild.");
                         }
                         break;
                     case 'M':
@@ -68,13 +103,13 @@
                                 month = value;
                                 state = State.MONTH;
                             } else {
-                                throw new Exception(errorMessage);
+                                throw new HyracksDataException(durationErrorMessage + ": wrong MONTH field.");
                             }
                         } else if (state.compareTo(State.MIN) < 0) {
                             minute = value;
                             state = State.MIN;
                         } else {
-                            throw new Exception(errorMessage);
+                            throw new HyracksDataException(durationErrorMessage + ": wrong MIN field.");
                         }
                         break;
                     case 'D':
@@ -82,14 +117,14 @@
                             day = value;
                             state = State.DAY;
                         } else {
-                            throw new Exception(errorMessage);
+                            throw new HyracksDataException(durationErrorMessage + ": wrong DAY field");
                         }
                         break;
                     case 'T':
                         if (state.compareTo(State.TIME) < 0) {
                             state = State.TIME;
                         } else {
-                            throw new Exception(errorMessage);
+                            throw new HyracksDataException(durationErrorMessage + ": wrong TIME field.");
                         }
                         break;
 
@@ -98,7 +133,7 @@
                             hour = value;
                             state = State.HOUR;
                         } else {
-                            throw new Exception(errorMessage);
+                            throw new HyracksDataException(durationErrorMessage + ": wrong HOUR field.");
                         }
                         break;
                     case '.':
@@ -110,7 +145,8 @@
                                     if (i < 4) {
                                         millisecond = millisecond * 10 + (charAccessor.getCharAt(offset + i) - '0');
                                     } else {
-                                        throw new Exception(errorMessage);
+                                        throw new HyracksDataException(durationErrorMessage
+                                                + ": wrong MILLISECOND field.");
                                     }
                                 } else {
                                     break;
@@ -119,18 +155,18 @@
                             offset += i;
                             state = State.MILLISEC;
                         } else {
-                            throw new Exception(errorMessage);
+                            throw new HyracksDataException(durationErrorMessage + ": wrong MILLISECOND field.");
                         }
                     case 'S':
                         if (state.compareTo(State.SEC) < 0) {
                             second = value;
                             state = State.SEC;
                         } else {
-                            throw new Exception(errorMessage);
+                            throw new HyracksDataException(durationErrorMessage + ": wrong SECOND field.");
                         }
                         break;
                     default:
-                        throw new Exception(errorMessage);
+                        throw new HyracksDataException(durationErrorMessage + ": wrong format for duration.");
 
                 }
                 value = 0;
@@ -138,7 +174,7 @@
         }
 
         if (state.compareTo(State.TIME) == 0) {
-            throw new Exception(errorMessage);
+            throw new HyracksDataException(durationErrorMessage + ": no time fields after time separator.");
         }
 
         short temp = 1;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java
new file mode 100644
index 0000000..d76f41d
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.base.temporal;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+
+public class ATimeParserFactory implements IValueParserFactory {
+
+    public static final IValueParserFactory INSTANCE = new ATimeParserFactory();
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String timeErrorMessage = "Wrong Input Format for a Time Value";
+
+    private ATimeParserFactory() {
+
+    }
+
+    @Override
+    public IValueParser createValueParser() {
+
+        final CharArrayCharSequenceAccessor charArrayAccessor = new CharArrayCharSequenceAccessor();
+
+        return new IValueParser() {
+
+            @Override
+            public void parse(char[] buffer, int start, int length, DataOutput out) throws HyracksDataException {
+                charArrayAccessor.reset(buffer, start, length);
+                try {
+                    out.writeInt(parseTimePart(charArrayAccessor));
+                } catch (IOException ex) {
+                    throw new HyracksDataException(ex);
+                }
+            }
+        };
+    }
+
+    /**
+     * Parse the given char sequence as a time string, and return the milliseconds represented by the time.
+     * 
+     * @param charAccessor
+     * @return
+     * @throws Exception
+     */
+    public static <T> int parseTimePart(ICharSequenceAccessor<T> charAccessor) throws HyracksDataException {
+
+        int length = charAccessor.getLength();
+        int offset = 0;
+
+        int hour = 0, min = 0, sec = 0, millis = 0;
+        int timezone = 0;
+
+        boolean isExtendedForm = false;
+        if (charAccessor.getCharAt(offset + 2) == ':') {
+            isExtendedForm = true;
+        }
+
+        if (isExtendedForm && (charAccessor.getCharAt(offset + 2) != ':' || charAccessor.getCharAt(offset + 5) != ':')) {
+            throw new HyracksDataException(timeErrorMessage + ": Missing colon in an extended time format.");
+        }
+        // hour
+        for (int i = 0; i < 2; i++) {
+            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+                hour = hour * 10 + charAccessor.getCharAt(offset + i) - '0';
+            } else {
+                throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in hour field");
+            }
+        }
+
+        if (hour < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.HOUR.ordinal()]
+                || hour > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.HOUR.ordinal()]) {
+            throw new HyracksDataException(timeErrorMessage + ": hour " + hour);
+        }
+
+        offset += (isExtendedForm) ? 3 : 2;
+
+        // minute
+        for (int i = 0; i < 2; i++) {
+            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+                min = min * 10 + charAccessor.getCharAt(offset + i) - '0';
+            } else {
+                throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in minute field");
+            }
+        }
+
+        if (min < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.MINUTE.ordinal()]
+                || min > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.MINUTE.ordinal()]) {
+            throw new HyracksDataException(timeErrorMessage + ": min " + min);
+        }
+
+        offset += (isExtendedForm) ? 3 : 2;
+
+        // second
+        for (int i = 0; i < 2; i++) {
+            if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+                sec = sec * 10 + charAccessor.getCharAt(offset + i) - '0';
+            } else {
+                throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in second field");
+            }
+        }
+
+        if (sec < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.SECOND.ordinal()]
+                || sec > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.SECOND.ordinal()]) {
+            throw new HyracksDataException(timeErrorMessage + ": sec " + sec);
+        }
+
+        offset += 2;
+
+        if ((isExtendedForm && length > offset && charAccessor.getCharAt(offset) == '.')
+                || (!isExtendedForm && length > offset)) {
+
+            offset += (isExtendedForm) ? 1 : 0;
+            int i = 0;
+            for (; i < 3 && offset + i < length; i++) {
+                if (charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9') {
+                    millis = millis * 10 + charAccessor.getCharAt(offset + i) - '0';
+                } else {
+                    break;
+                }
+            }
+
+            offset += i;
+
+            for (; i < 3; i++) {
+                millis = millis * 10;
+            }
+
+            // error is thrown if more than three digits are seen for the millisecond part
+            if (charAccessor.getLength() > offset && charAccessor.getCharAt(offset) >= '0'
+                    && charAccessor.getCharAt(offset) <= '9') {
+                throw new HyracksDataException(timeErrorMessage + ": too many fields for millisecond.");
+            }
+        }
+
+        if (length > offset) {
+            timezone = parseTimezonePart(charAccessor, offset);
+        }
+
+        return GregorianCalendarSystem.getInstance().getChronon(hour, min, sec, millis, timezone);
+    }
+
+    /**
+     * Parse the given char sequence as a time string, and return the milliseconds represented by the time.
+     * 
+     * @param charAccessor
+     * @return
+     * @throws Exception
+     */
+    public static <T> int parseTimezonePart(ICharSequenceAccessor<T> charAccessor, int offset)
+            throws HyracksDataException {
+        int timezone = 0;
+
+        if (charAccessor.getCharAt(offset) != 'Z') {
+            if ((charAccessor.getCharAt(offset) != '+' && charAccessor.getCharAt(offset) != '-')) {
+                throw new HyracksDataException("Wrong timezone format: missing sign or missing colon for a time zone");
+            }
+
+            short timezoneHour = 0;
+            short timezoneMinute = 0;
+
+            for (int i = 0; i < 2; i++) {
+                if ((charAccessor.getCharAt(offset + 1 + i) >= '0' && charAccessor.getCharAt(offset + 1 + i) <= '9')) {
+                    timezoneHour = (short) (timezoneHour * 10 + charAccessor.getCharAt(offset + 1 + i) - '0');
+                } else {
+                    throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in timezone hour field");
+                }
+            }
+
+            if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
+                    || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
+                throw new HyracksDataException(timeErrorMessage + ": time zone hour " + timezoneHour);
+            }
+
+            int temp_offset = (charAccessor.getCharAt(offset + 3) == ':') ? 1 : 0;
+
+            for (int i = 0; i < 2; i++) {
+                if ((charAccessor.getCharAt(offset + temp_offset + 3 + i) >= '0' && charAccessor.getCharAt(offset
+                        + temp_offset + 3 + i) <= '9')) {
+                    timezoneMinute = (short) (timezoneMinute * 10
+                            + charAccessor.getCharAt(offset + temp_offset + 3 + i) - '0');
+                } else {
+                    throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in timezone minute field");
+                }
+            }
+
+            if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
+                    || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
+                throw new HyracksDataException(timeErrorMessage + ": time zone minute " + timezoneMinute);
+            }
+
+            if (charAccessor.getCharAt(offset) == '-') {
+                timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
+            } else {
+                timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+            }
+        }
+        return timezone;
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/CharArrayCharSequenceAccessor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/CharArrayCharSequenceAccessor.java
new file mode 100644
index 0000000..404f0ee
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/CharArrayCharSequenceAccessor.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.base.temporal;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
+
+public class CharArrayCharSequenceAccessor implements ICharSequenceAccessor<char[]> {
+
+    private char[] buf;
+    private int offset;
+    private int length;
+    
+    @Override
+    public char getCharAt(int index) throws AsterixRuntimeException {
+        if (index < 0 || index >= length) {
+            throw new AsterixRuntimeException("Byte array char accessor is out of bound: " + index + ":" + length);
+        }
+        return (char) (buf[index + offset]);
+    }
+
+    /**
+     * Reset the wrapped byte array.
+     * 
+     * @param obj
+     *            The byte array to be wrapped
+     * @param beginOffset
+     *            The offset of the string stored in the byte array.
+     * @param offset
+     *            The offset of the substring of the string stored (offset from the beginOffset).
+     */
+    public void reset(char[] obj, int offset, int length) {
+        this.buf = obj;
+        this.offset = offset;
+        this.length = length;
+    }
+
+    @Override
+    public int getLength() {
+        return length;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java
index d6e3303..77e8b50 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java
@@ -22,8 +22,8 @@
 import edu.uci.ics.asterix.om.base.ADate;
 import edu.uci.ics.asterix.om.base.AMutableDate;
 import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -88,7 +88,7 @@
                                 int stringLength = (serString[1] & 0xff << 8) + (serString[2] & 0xff << 0);
 
                                 charAccessor.reset(serString, 3, stringLength);
-                                long chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, true);
+                                long chrononTimeInMs = ADateParserFactory.parseDatePart(charAccessor, true);
 
                                 short temp = 0;
                                 if (chrononTimeInMs < 0
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java
index abbe033..3f91571 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java
@@ -22,8 +22,9 @@
 import edu.uci.ics.asterix.om.base.ADateTime;
 import edu.uci.ics.asterix.om.base.AMutableDateTime;
 import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -99,11 +100,11 @@
                                 timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11)
                                         : (short) (9);
 
-                                long chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, false);
+                                long chrononTimeInMs = ADateParserFactory.parseDatePart(charAccessor, false);
 
                                 charAccessor.reset(serString, 3 + timeOffset, stringLength - timeOffset);
 
-                                chrononTimeInMs += ADateAndTimeParser.parseTimePart(charAccessor);
+                                chrononTimeInMs += ATimeParserFactory.parseTimePart(charAccessor);
 
                                 aDateTime.setValue(chrononTimeInMs);
                                 datetimeSerde.serialize(aDateTime, out);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADurationConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADurationConstructorDescriptor.java
index 93c6c15..7b48738 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADurationConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADurationConstructorDescriptor.java
@@ -21,7 +21,7 @@
 import edu.uci.ics.asterix.om.base.ADuration;
 import edu.uci.ics.asterix.om.base.AMutableDuration;
 import edu.uci.ics.asterix.om.base.ANull;
-import edu.uci.ics.asterix.om.base.temporal.ADurationParser;
+import edu.uci.ics.asterix.om.base.temporal.ADurationParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -88,7 +88,7 @@
 
                                 charAccessor.reset(serString, 3, stringLength);
 
-                                ADurationParser.parse(charAccessor, aDuration);
+                                ADurationParserFactory.parseDuration(charAccessor, aDuration);
 
                                 durationSerde.serialize(aDuration, out);
                             } else if (serString[0] == SER_NULL_TYPE_TAG) {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateConstructorDescriptor.java
index d98b1bc..83489ef 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateConstructorDescriptor.java
@@ -22,8 +22,8 @@
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
 import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -101,7 +101,7 @@
 
                                 // start date
                                 charAccessor.reset(argOut0.getByteArray(), 3, stringLength);
-                                long intervalStart = ADateAndTimeParser.parseDatePart(charAccessor, true)
+                                long intervalStart = ADateParserFactory.parseDatePart(charAccessor, true)
                                         / GregorianCalendarSystem.CHRONON_OF_DAY;
                                 // end date
 
@@ -109,7 +109,7 @@
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
 
                                 charAccessor.reset(argOut1.getByteArray(), 3, stringLength);
-                                long intervalEnd = ADateAndTimeParser.parseDatePart(charAccessor, true)
+                                long intervalEnd = ADateParserFactory.parseDatePart(charAccessor, true)
                                         / GregorianCalendarSystem.CHRONON_OF_DAY;
 
                                 if (intervalEnd < intervalStart) {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateTimeConstructorDescriptor.java
index dbc14ea..dab5efd 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateTimeConstructorDescriptor.java
@@ -22,8 +22,9 @@
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
 import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -111,9 +112,9 @@
                                 // if extended form 11, else 9
                                 timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11)
                                         : (short) (9);
-                                long intervalStart = ADateAndTimeParser.parseDatePart(charAccessor, false);
+                                long intervalStart = ADateParserFactory.parseDatePart(charAccessor, false);
                                 charAccessor.reset(argOut0.getByteArray(), 3 + timeOffset, stringLength - timeOffset);
-                                intervalStart += ADateAndTimeParser.parseTimePart(charAccessor);
+                                intervalStart += ATimeParserFactory.parseTimePart(charAccessor);
 
                                 // end date
 
@@ -132,9 +133,9 @@
                                 // if extended form 11, else 9
                                 timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11)
                                         : (short) (9);
-                                long intervalEnd = ADateAndTimeParser.parseDatePart(charAccessor, false);
+                                long intervalEnd = ADateParserFactory.parseDatePart(charAccessor, false);
                                 charAccessor.reset(argOut1.getByteArray(), 3 + timeOffset, stringLength - timeOffset);
-                                intervalEnd += ADateAndTimeParser.parseTimePart(charAccessor);
+                                intervalEnd += ATimeParserFactory.parseTimePart(charAccessor);
 
                                 if (intervalEnd < intervalStart) {
                                     throw new AlgebricksException(
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromTimeConstructorDescriptor.java
index 36fed9a..701a439 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromTimeConstructorDescriptor.java
@@ -22,8 +22,8 @@
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
 import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -101,7 +101,7 @@
                                         + (argOut0.getByteArray()[2] & 0xff << 0);
 
                                 charAccessor.reset(argOut0.getByteArray(), 3, stringLength);
-                                long intervalStart = ADateAndTimeParser.parseTimePart(charAccessor);
+                                long intervalStart = ATimeParserFactory.parseTimePart(charAccessor);
                                 if (intervalStart < 0) {
                                     intervalStart += GregorianCalendarSystem.CHRONON_OF_DAY;
                                 }
@@ -112,7 +112,7 @@
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
 
                                 charAccessor.reset(argOut1.getByteArray(), 3, stringLength);
-                                long intervalEnd = ADateAndTimeParser.parseTimePart(charAccessor);
+                                long intervalEnd = ATimeParserFactory.parseTimePart(charAccessor);
                                 if (intervalEnd < 0) {
                                     intervalEnd += GregorianCalendarSystem.CHRONON_OF_DAY;
                                 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
index 806fca6..15f124a 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
@@ -23,9 +23,9 @@
 import edu.uci.ics.asterix.om.base.AMutableDuration;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
 import edu.uci.ics.asterix.om.base.ANull;
-import edu.uci.ics.asterix.om.base.temporal.ADurationParser;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ADurationParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
 import edu.uci.ics.asterix.om.base.temporal.DurationArithmeticOperations;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
@@ -105,14 +105,14 @@
                                         + (argOut0.getByteArray()[2] & 0xff << 0);
 
                                 charAccessor.reset(argOut0.getByteArray(), 3, stringLength);
-                                long intervalStart = ADateAndTimeParser.parseDatePart(charAccessor, true);
+                                long intervalStart = ADateParserFactory.parseDatePart(charAccessor, true);
                                 // duration
 
                                 stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
 
                                 charAccessor.reset(argOut1.getByteArray(), 3, stringLength);
-                                ADurationParser.parse(charAccessor, aDuration);
+                                ADurationParserFactory.parseDuration(charAccessor, aDuration);
 
                                 long intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
                                         aDuration.getMonths(), aDuration.getMilliseconds());
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java
index 79e68a2..4a02d55 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java
@@ -23,9 +23,10 @@
 import edu.uci.ics.asterix.om.base.AMutableDuration;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
 import edu.uci.ics.asterix.om.base.ANull;
-import edu.uci.ics.asterix.om.base.temporal.ADurationParser;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ADurationParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
 import edu.uci.ics.asterix.om.base.temporal.DurationArithmeticOperations;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -115,9 +116,9 @@
                                 // if extended form 11, else 9
                                 timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11)
                                         : (short) (9);
-                                long intervalStart = ADateAndTimeParser.parseDatePart(charAccessor, false);
+                                long intervalStart = ADateParserFactory.parseDatePart(charAccessor, false);
                                 charAccessor.reset(argOut0.getByteArray(), 3 + timeOffset, stringLength - timeOffset);
-                                intervalStart += ADateAndTimeParser.parseTimePart(charAccessor);
+                                intervalStart += ATimeParserFactory.parseTimePart(charAccessor);
 
                                 // duration
 
@@ -125,7 +126,7 @@
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
 
                                 charAccessor.reset(argOut1.getByteArray(), 3, stringLength);
-                                ADurationParser.parse(charAccessor, aDuration);
+                                ADurationParserFactory.parseDuration(charAccessor, aDuration);
 
                                 long intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
                                         aDuration.getMonths(), aDuration.getMilliseconds());
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java
index 3bdf15e..0d98710 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java
@@ -23,9 +23,9 @@
 import edu.uci.ics.asterix.om.base.AMutableDuration;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
 import edu.uci.ics.asterix.om.base.ANull;
-import edu.uci.ics.asterix.om.base.temporal.ADurationParser;
+import edu.uci.ics.asterix.om.base.temporal.ADurationParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
 import edu.uci.ics.asterix.om.base.temporal.DurationArithmeticOperations;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
@@ -105,7 +105,7 @@
                                         + (argOut0.getByteArray()[2] & 0xff << 0);
 
                                 charAccessor.reset(argOut0.getByteArray(), 3, stringLength);
-                                int intervalStart = ADateAndTimeParser.parseTimePart(charAccessor);
+                                int intervalStart = ATimeParserFactory.parseTimePart(charAccessor);
 
                                 if (intervalStart < 0) {
                                     intervalStart += GregorianCalendarSystem.CHRONON_OF_DAY;
@@ -117,7 +117,7 @@
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
 
                                 charAccessor.reset(argOut1.getByteArray(), 3, stringLength);
-                                ADurationParser.parse(charAccessor, aDuration);
+                                ADurationParserFactory.parseDuration(charAccessor, aDuration);
 
                                 if (aDuration.getMonths() != 0) {
                                     throw new AlgebricksException("Cannot add a year-month duration to a time value.");
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
index 0e5fe8d..bba2266 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
@@ -22,8 +22,8 @@
 import edu.uci.ics.asterix.om.base.AMutableTime;
 import edu.uci.ics.asterix.om.base.ANull;
 import edu.uci.ics.asterix.om.base.ATime;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -88,7 +88,7 @@
                                 int stringLength = (serString[1] & 0xff << 8) + (serString[2] & 0xff << 0);
 
                                 charAccessor.reset(serString, 3, stringLength);
-                                int chrononTimeInMs = ADateAndTimeParser.parseTimePart(charAccessor);
+                                int chrononTimeInMs = ATimeParserFactory.parseTimePart(charAccessor);
 
                                 if (chrononTimeInMs < 0) {
                                     chrononTimeInMs += GregorianCalendarSystem.CHRONON_OF_DAY;
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
index 5449af2..634a929 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
@@ -20,7 +20,7 @@
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.ANull;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem.Fields;
@@ -117,7 +117,7 @@
 
                             charAccessor.reset(argOut1.getByteArray(), 3, stringLength);
 
-                            int timezone = ADateAndTimeParser.parseTimezonePart(charAccessor, 0);
+                            int timezone = ATimeParserFactory.parseTimezonePart(charAccessor, 0);
 
                             if (!calInstance.validateTimeZone(timezone)) {
                                 throw new AlgebricksException("Wrong format for a time zone string!");
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
index 1c6e838..74818f0 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
@@ -20,7 +20,7 @@
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.ANull;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem.Fields;
@@ -117,7 +117,7 @@
 
                             charAccessor.reset(argOut1.getByteArray(), 3, stringLength);
 
-                            int timezone = ADateAndTimeParser.parseTimezonePart(charAccessor, 0);
+                            int timezone = ATimeParserFactory.parseTimezonePart(charAccessor, 0);
 
                             if (!calInstance.validateTimeZone(timezone)) {
                                 throw new AlgebricksException("Wrong format for a time zone string!");