Addressing review comments from Zach on r338 for temporal types fix. The following changes are done:
- Removed the timezone information for date data type.
- Refactored the parsers for date, time and duration to reuse the code between serDer and constructor.
- Added comments for opaque codes.
- We keep the concept of negative duration; although it is not a part in the ISO 8601 standard (but XML does), it would be used later when we need to support arithmetic operations between time instances. 
- Date, time and duration is updated to fail-fast if the millisecond field is more than 3 digits.
- Bug fixing: missing "T" separator in ADateTime type. 

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_temporal_fixes@543 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-app/data/nontagged/tempData.json b/asterix-app/data/nontagged/tempData.json
index a439ab0..a40a254 100644
--- a/asterix-app/data/nontagged/tempData.json
+++ b/asterix-app/data/nontagged/tempData.json
@@ -1,2 +1,2 @@
-{ "id": 10, "date": date("2011-01-27"), "time": time("12:20:30"), "datetime": datetime("1951-12-27T12:20:30"),  "duration": duration("P30Y10M15DT10H30M50S"), "date2": date("2011-01-27-05:00"), "time2": time("12:20:30.999-05:00"), "datetime2": datetime("1951-12-27T12:20:30.250-08:45"),  "duration2": duration("P10M15DT10H50S"), "date3": date("-2011-01-27-05:00"), "time3": time("12:20:30.999Z"), "datetime3": datetime("-1951-12-27T12:20:30.250-08:15"),  "duration3": duration("-PT50S"), "date4": date("-2011-01-27Z"), "time4": time("12:20:30Z"), "datetime4": datetime("-1951-12-27T12:20:30.250Z"), "duration4": duration("-P10M"), "date5": date("2011-01-27"), "time5": time("12:20:30"), "datetime5": datetime("1951-12-27T12:20:30"),  "duration5": duration("P30Y10M15DT10H30M50S") }
+{ "id": 10, "date": date("2011-01-27"), "time": time("12:20:30"), "datetime": datetime("1951-12-27T12:20:30"),  "duration": duration("P30Y10M15DT10H30M50S"), "date2": date("2011-01-27"), "time2": time("12:20:30.999-05:00"), "datetime2": datetime("1951-12-27T12:20:30.250-08:45"),  "duration2": duration("P10M15DT10H50S"), "date3": date("-2011-01-27"), "time3": time("12:20:30.999Z"), "datetime3": datetime("-1951-12-27T12:20:30.250-08:15"),  "duration3": duration("-PT50S"), "date4": date("-2011-01-27"), "time4": time("12:20:30Z"), "datetime4": datetime("-1951-12-27T12:20:30.250Z"), "duration4": duration("-P10M"), "date5": date("2011-01-27"), "time5": time("12:20:30"), "datetime5": datetime("1951-12-27T12:20:30"),  "duration5": duration("P30Y10M15DT10H30M50S") }
 
diff --git a/asterix-app/data/nontagged/tempData.txt b/asterix-app/data/nontagged/tempData.txt
index 8790101..0afeb6f 100644
--- a/asterix-app/data/nontagged/tempData.txt
+++ b/asterix-app/data/nontagged/tempData.txt
@@ -1,4 +1,4 @@
 10|date("2011-01-27")|time("12:20:30")|datetime("1951-12-27T12:20:30")|duration("P30Y10M15DT10H30M50S")
-20|date("2011-01-27-05:00")|time("12:20:30.999-05:00")|datetime("1951-12-27T12:20:30.250-08:45")|duration("P10M15DT10H50S")
-30|date("-2011-01-27-05:00")|time("12:20:30.999Z")|datetime("-1951-12-27T12:20:30.250-08:15")|duration("-PT50S")
-40|date("-2011-01-27Z")|time("12:20:30Z")|datetime("-1951-12-27T12:20:30.250Z")|duration("-P10M")
+20|date("2011-01-27")|time("12:20:30.999-05:00")|datetime("1951-12-27T12:20:30.250-08:45")|duration("P10M15DT10H50S")
+30|date("-2011-01-27")|time("12:20:30.999Z")|datetime("-1951-12-27T12:20:30.250-08:15")|duration("-PT50S")
+40|date("-2011-01-27")|time("12:20:30Z")|datetime("-1951-12-27T12:20:30.250Z")|duration("-P10M")
diff --git a/asterix-app/src/test/resources/runtimets/queries/constructor/date_01.aql b/asterix-app/src/test/resources/runtimets/queries/constructor/date_01.aql
index 9cc3d15..9bbfb9d 100644
--- a/asterix-app/src/test/resources/runtimets/queries/constructor/date_01.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/constructor/date_01.aql
@@ -4,18 +4,14 @@
 
 write output to nc1:"rttest/constructor_date_01.adm";
 
-let $c1 := date("2010-10-30+05:00")
-let $c2 := date("2010-10-30-10:15")
-let $c3 := date("1987-11-19")
-let $c4 := date("1987-11-19Z")
-let $c5 := date("-1987-11-19+08:30")
-let $c6 := date("0001-12-27")
-let $c7 := date("-1951-01-27-01:45")
-let $c8 := date("-2043-11-19Z")
-let $c9 := date("-19280329-0630")
-let $c10 := date("-19280329+0630")
-let $c11 := date("-19280329")
-let $c12 := date("-19280229")
-let $c13 := date("-19280301+0630")
-return {"date1": $c1, "date2": $c2, "date3": $c3, "date4": $c4, "date5": $c5, "date6": $c6, "date7": $c7, "date8": $c8, "date9": $c9, "date10": $c10, "date11": $c11, "date12": $c12, "date13": $c13}
+let $c1 := date("2010-10-30")
+let $c2 := date("1987-11-19")
+let $c3 := date("-1987-11-19")
+let $c4 := date("0001-12-27")
+let $c5 := date("-1951-12-27")
+let $c6 := date("-2043-11-19")
+let $c7 := date("-19280329")
+let $c8 := date("19280329")
+
+return {"date1": $c1, "date2": $c2, "date3": $c3, "date4": $c4, "date5": $c5, "date6": $c6, "date7": $c7, "date8": $c8}
 
diff --git a/asterix-app/src/test/resources/runtimets/queries/constructor/datetime_01.aql b/asterix-app/src/test/resources/runtimets/queries/constructor/datetime_01.aql
index b883b8a..c4163d8 100644
--- a/asterix-app/src/test/resources/runtimets/queries/constructor/datetime_01.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/constructor/datetime_01.aql
@@ -11,12 +11,12 @@
 let $c5 := datetime("-1987-11-19T10:50:56.099-05:30")
 let $c6 := datetime("-0001-11-19T10:50:56.719Z")
 let $c7 := datetime("1951-12-27T12:20:15Z")
-let $c8 := datetime("2043-11-19T10:50:56.719938747Z")
-let $c9 := datetime("-19280329174937374-0630")
-let $c10 := datetime("-19280329174937374+0630")
-let $c11 := datetime("-19280329174937374")
-let $c12 := datetime("-19280329174937374847374+0630")
-let $c13 := datetime("-1928032917493737+0630")
-let $c14 := datetime("-1928030105493737+0630")
+let $c8 := datetime("2043-11-19T10:50:56.719Z")
+let $c9 := datetime("-19280329T174937374-0630")
+let $c10 := datetime("-19280329T174937374+0630")
+let $c11 := datetime("-19280329T174937374")
+let $c12 := datetime("-19280329T174937374+0630")
+let $c13 := datetime("-19280329T17493737+0630")
+let $c14 := datetime("-19280301T05493737+0630")
 return {"datetime1": $c1, "datetime2": $c2, "datetime3": $c3, "datetime4": $c4, "datetime5": $c5, "datetime6": $c6, "datetime7": $c7, "datetime8": $c8, "datetime9": $c9, "datetime10": $c10, "datetime11": $c11, "datetime12": $c12, "datetime13": $c13, "datetime14": $c14}
 
diff --git a/asterix-app/src/test/resources/runtimets/queries/constructor/duration_01.aql b/asterix-app/src/test/resources/runtimets/queries/constructor/duration_01.aql
index 4d9df8c..59a3634 100644
--- a/asterix-app/src/test/resources/runtimets/queries/constructor/duration_01.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/constructor/duration_01.aql
@@ -15,7 +15,6 @@
 let $c9 := duration("P120D")
 let $c10 := duration("-P28M")
 let $c11 := duration("PT29M90.937S")
-let $c12 := duration("P300Y15M60DT300H98M482.43S")
-let $c13 := duration("P300Y15M60DT300H98M482.43493848S")
-return {"duration1": $c1, "duration2": $c2, "duration3": $c3, "duration4": $c4, "duration5": $c5, "duration6": $c6, "duration7": $c7, "duration8": $c8, "duration9": $c9, "duration10": $c10, "duration11": $c11, "duration12": $c12, "duration13": $c13}
+let $c12 := duration("P300Y15M60DT300H98M482.435S")
+return {"duration1": $c1, "duration2": $c2, "duration3": $c3, "duration4": $c4, "duration5": $c5, "duration6": $c6, "duration7": $c7, "duration8": $c8, "duration9": $c9, "duration10": $c10, "duration11": $c11, "duration12": $c12}
 
diff --git a/asterix-app/src/test/resources/runtimets/queries/constructor/time_01.aql b/asterix-app/src/test/resources/runtimets/queries/constructor/time_01.aql
index bb5d313..4a040a1 100644
--- a/asterix-app/src/test/resources/runtimets/queries/constructor/time_01.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/constructor/time_01.aql
@@ -12,8 +12,8 @@
 let $c6 := time("00:00:00.000+14:45")
 let $c7 := time("12:59:00.019-01:00")
 let $c8 := time("12:59:00.01-01:00")
-let $c9 := time("12:59:00.0193823-01:00")
+let $c9 := time("12:59:00.019-01:00")
 let $c10 := time("12590001-0100")
-let $c11 := time("125900019382382398238-0100")
+let $c11 := time("125900019-0100")
 return {"time1": $c1, "time2": $c2, "time3": $c3, "time4": $c4, "time5": $c5, "time6": $c6, "time7": $c7, "time8": $c8, "time9": $c9, "time10": $c10, "time11": $c11}
 
diff --git a/asterix-app/src/test/resources/runtimets/results/constructor/date_01.adm b/asterix-app/src/test/resources/runtimets/results/constructor/date_01.adm
index 12f5755..2a90c4d 100644
--- a/asterix-app/src/test/resources/runtimets/results/constructor/date_01.adm
+++ b/asterix-app/src/test/resources/runtimets/results/constructor/date_01.adm
@@ -1 +1 @@
-{ "date1": date("2010-10-29Z"), "date2": date("2010-10-30Z"), "date3": date("1987-11-19Z"), "date4": date("1987-11-19Z"), "date5": date("-1987-11-18Z"), "date6": date("0001-12-27Z"), "date7": date("-1951-01-27Z"), "date8": date("-2043-11-19Z"), "date9": date("-1928-03-29Z"), "date10": date("-1928-03-28Z"), "date11": date("-1928-03-29Z"), "date12": date("-1928-02-29Z"), "date13": date("-1928-02-29Z") }
\ No newline at end of file
+{ "date1": date("2010-10-30"), "date2": date("1987-11-19"), "date3": date("-1987-11-19"), "date4": date("0001-12-27"), "date5": date("-1951-12-27"), "date6": date("-2043-11-19"), "date7": date("-1928-03-29"), "date8": date("1928-03-29") }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/constructor/duration_01.adm b/asterix-app/src/test/resources/runtimets/results/constructor/duration_01.adm
index d9c8359..3a9cbb7 100644
--- a/asterix-app/src/test/resources/runtimets/results/constructor/duration_01.adm
+++ b/asterix-app/src/test/resources/runtimets/results/constructor/duration_01.adm
@@ -1 +1 @@
-{ "duration1": duration("P30Y10M25DT13H12M50S"), "duration2": duration("P0Y0M25DT13H12M50S"), "duration3": duration("P0Y0M0DT13H12M50S"), "duration4": duration("P30Y0M0DT0H12M0S"), "duration5": duration("P0Y0M0DT13H0M0S"), "duration6": duration("-P30Y10M25DT13H12M50S"), "duration7": duration("-P0Y0M25DT13H12M50S"), "duration8": duration("-P0Y0M0DT13H0M50S"), "duration9": duration("P0Y0M120DT0H0M0S"), "duration10": duration("-P2Y4M0DT0H0M0S"), "duration11": duration("P0Y0M0DT0H30M30.937S"), "duration12": duration("P301Y3M72DT13H46M2.43S"), "duration13": duration("P301Y3M72DT13H46M2.434S") }
+{ "duration1": duration("P30Y10M25DT13H12M50S"), "duration2": duration("P25DT13H12M50S"), "duration3": duration("PT13H12M50S"), "duration4": duration("P30YT12M"), "duration5": duration("PT13H"), "duration6": duration("-P30Y10M25DT13H12M50S"), "duration7": duration("-P25DT13H12M50S"), "duration8": duration("-PT13H50S"), "duration9": duration("P120D"), "duration10": duration("-P2Y4M"), "duration11": duration("PT30M30.937S"), "duration12": duration("P301Y3M72DT13H46M2.435S") }
diff --git a/asterix-app/src/test/resources/runtimets/results/scan/alltypes_01.adm b/asterix-app/src/test/resources/runtimets/results/scan/alltypes_01.adm
index 06adc49..64aee7c 100644
--- a/asterix-app/src/test/resources/runtimets/results/scan/alltypes_01.adm
+++ b/asterix-app/src/test/resources/runtimets/results/scan/alltypes_01.adm
@@ -1 +1 @@
-{ "id": 10, "name": "Nancy", "age": 32.5f, "salary": 12.0d, "married": true, "interests": {{ "reading", "writing" }}, "children": [ "Brad", "Scott" ], "address": { "number": 8389, "street": "Hill St.", "city": "Mountain View" }, "dob": date("-2011-01-27Z"), "time": time("12:20:30.000Z"), "datetime": datetime("-1951-12-27T12:20:30.000Z"), "duration": duration("P10Y11M12DT10H50M30S"), "location2d": point("41.0,44.0"), "location3d": point3d("44.0,13.0,41.0"), "line": line("10.1,11.1 10.2,11.2"), "polygon": polygon("1.2,1.3 2.1,2.5 3.5,3.6 4.6,4.8"), "circle": circle("10.1,11.1 10.2") }
+{ "id": 10, "name": "Nancy", "age": 32.5f, "salary": 12.0d, "married": true, "interests": {{ "reading", "writing" }}, "children": [ "Brad", "Scott" ], "address": { "number": 8389, "street": "Hill St.", "city": "Mountain View" }, "dob": date("-2011-01-27"), "time": time("12:20:30.000Z"), "datetime": datetime("-1951-12-27T12:20:30.000Z"), "duration": duration("P10Y11M12DT10H50M30S"), "location2d": point("41.0,44.0"), "location3d": point3d("44.0,13.0,41.0"), "line": line("10.1,11.1 10.2,11.2"), "polygon": polygon("1.2,1.3 2.1,2.5 3.5,3.6 4.6,4.8"), "circle": circle("10.1,11.1 10.2") }
diff --git a/asterix-app/src/test/resources/runtimets/results/scan/temp_types_01.adm b/asterix-app/src/test/resources/runtimets/results/scan/temp_types_01.adm
index 7d57c24..4ad4f1c 100644
--- a/asterix-app/src/test/resources/runtimets/results/scan/temp_types_01.adm
+++ b/asterix-app/src/test/resources/runtimets/results/scan/temp_types_01.adm
@@ -1 +1 @@
-{ "id": 10, "date": date("2011-01-27Z"), "time": time("12:20:30.000Z"), "datetime": datetime("1951-12-27T12:20:30.000Z"), "duration": duration("P30Y10M15DT10H30M50S"), "date2": date("2011-01-27Z"), "time2": time("17:20:30.999Z"), "datetime2": datetime("1951-12-27T21:05:30.250Z"), "duration2": duration("P0Y10M15DT10H0M50S"), "date3": date("-2011-01-27Z"), "time3": time("12:20:30.999Z"), "datetime3": datetime("-1951-12-27T20:35:30.250Z"), "duration3": duration("-P0Y0M0DT0H0M50S"), "date4": date("-2011-01-27Z"), "time4": time("12:20:30.000Z"), "datetime4": datetime("-1951-12-27T12:20:30.250Z"), "duration4": duration("-P0Y10M0DT0H0M0S"), "date5": date("2011-01-27Z"), "time5": time("12:20:30.000Z"), "datetime5": datetime("1951-12-27T12:20:30.000Z"), "duration5": duration("P30Y10M15DT10H30M50S") }
\ No newline at end of file
+{ "id": 10, "date": date("2011-01-27"), "time": time("12:20:30.000Z"), "datetime": datetime("1951-12-27T12:20:30.000Z"), "duration": duration("P30Y10M15DT10H30M50S"), "date2": date("2011-01-27"), "time2": time("17:20:30.999Z"), "datetime2": datetime("1951-12-27T21:05:30.250Z"), "duration2": duration("P10M15DT10H50S"), "date3": date("-2011-01-27"), "time3": time("12:20:30.999Z"), "datetime3": datetime("-1951-12-27T20:35:30.250Z"), "duration3": duration("-PT50S"), "date4": date("-2011-01-27"), "time4": time("12:20:30.000Z"), "datetime4": datetime("-1951-12-27T12:20:30.250Z"), "duration4": duration("-P10M"), "date5": date("2011-01-27"), "time5": time("12:20:30.000Z"), "datetime5": datetime("1951-12-27T12:20:30.000Z"), "duration5": duration("P30Y10M15DT10H30M50S") }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/scan/temp_types_02.adm b/asterix-app/src/test/resources/runtimets/results/scan/temp_types_02.adm
index 5f39ed9..f0b6815 100644
--- a/asterix-app/src/test/resources/runtimets/results/scan/temp_types_02.adm
+++ b/asterix-app/src/test/resources/runtimets/results/scan/temp_types_02.adm
@@ -1,4 +1,4 @@
-{ "id": 10, "date": date("2011-01-27+00:00"), "time": time("12:20:30.000Z"), "datetime": datetime("1951-12-27T12:20:30.000+00:00"), "duration": duration("P30Y10M15DT10H30M50S") }
-{ "id": 20, "date": date("2011-01-27-05:00"), "time": time("17:20:30.999Z"), "datetime": datetime("1951-12-27T12:20:30.240-08:45"), "duration": duration("P0Y10M15DT10H0M50S") }
-{ "id": 30, "date": date("-2011-01-27-05:00"), "time": time("12:20:30.999Z"), "datetime": datetime("-1951-12-27T12:20:30.240-08:15"), "duration": duration("-P0Y0M0DT0H0M50S") }
-{ "id": 40, "date": date("-2011-01-27+00:00"), "time": time("12:20:30.000Z"), "datetime": datetime("-1951-12-27T12:20:30.240+00:00"), "duration": duration("-P0Y10M0DT0H0M0S") }
+{ "id": 10, "date": date("2011-01-27"), "time": time("12:20:30.000Z"), "datetime": datetime("1951-12-27T12:20:30.000+00:00"), "duration": duration("P30Y10M15DT10H30M50S") }
+{ "id": 20, "date": date("2011-01-27"), "time": time("17:20:30.999Z"), "datetime": datetime("1951-12-27T12:20:30.240-08:45"), "duration": duration("P10M15DT10H50S") }
+{ "id": 30, "date": date("-2011-01-27"), "time": time("12:20:30.999Z"), "datetime": datetime("-1951-12-27T12:20:30.240-08:15"), "duration": duration("-PT50S") }
+{ "id": 40, "date": date("-2011-01-27"), "time": time("12:20:30.000Z"), "datetime": datetime("-1951-12-27T12:20:30.240+00:00"), "duration": duration("-P10M") }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADatePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADatePrinter.java
index 0895630..cd2b8c56 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADatePrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADatePrinter.java
@@ -31,14 +31,7 @@
 
         ps.print("date(\"");
         ps.append(String.format(year < 0 ? "%05d" : "%04d", year)).append("-").append(String.format("%02d", month))
-                .append("-").append(String.format("%02d", calendar.getDayOfMonthYear(chrononTime, year, month)))
-                .append("Z");
+                .append("-").append(String.format("%02d", calendar.getDayOfMonthYear(chrononTime, year, month)));
         ps.print("\")");
-        //        int year = AInt16SerializerDeserializer.getShort(b, s + 1) >> 1;
-        //        int month = (AInt16SerializerDeserializer.getShort(b, s + 1) & 0x0001) * 8 + ((b[s + 3] >> 5) & 0x07);
-        //        int day = b[s + 3] & 0x1f;
-        //        byte timezone = b[s + 4];
-        //        ps.format("date(\"" + (year < 0 ? "%+05d" : "%04d") + "-%02d-%02d%+03d:%02d\")", year, month, day,
-        //                timezone / 4, timezone % 4 * ((timezone >= 0) ? 15 : -15));
     }
 }
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADateTimePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADateTimePrinter.java
index 5fd6905..fdd6b18 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADateTimePrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADateTimePrinter.java
@@ -34,49 +34,5 @@
                 .append(String.format("%02d", calendar.getSecOfMin(chrononTime))).append(".")
                 .append(String.format("%03d", calendar.getMillisOfSec(chrononTime))).append("Z");
         ps.print("\")");
-        //        int year = AInt16SerializerDeserializer.getShort(b, s + 1) >> 1;
-        //        int month = (AInt16SerializerDeserializer.getShort(b, s + 1) & 0x0001) * 8 + ((b[s + 3] >> 5) & 0x07);
-        //
-        //        int day = b[s + 3] & 0x1f;
-        //        byte timezone = b[s + 4];
-        //
-        //        int time = AInt32SerializerDeserializer.getInt(b, s + 5);
-        //        // int msec = (time) * 20 % 1000;
-        //        // int sec = (time) * 20 % 60000 / 1000;
-        //        // int min = (time) * 20 % 3600000 / 60000;
-        //        // int hour = (time) * 20 % 216000000 / 3600000;
-        //
-        //        ps.print("datetime(\"");
-        //        if (year < 0) {
-        //            ps.print("-");
-        //        }
-        //        int y = Math.abs(year);
-        //        if (y < 1000) {
-        //            ps.print("0");
-        //        }
-        //        if (y < 100) {
-        //            ps.print("0");
-        //        }
-        //        if (y < 10) {
-        //            ps.print("0");
-        //        }
-        //        try {
-        //            WriteValueTools.writeInt(y, ps);
-        //            ps.print("-");
-        //            if (month < 10) {
-        //                ps.print("0");
-        //            }
-        //            WriteValueTools.writeInt(month, ps);
-        //            ps.print("-");
-        //            if (day < 10) {
-        //                ps.print("0");
-        //            }
-        //            WriteValueTools.writeInt(day, ps);
-        //            ps.print("T");
-        //        } catch (IOException e) {
-        //            throw new AlgebricksException(e);
-        //        }
-        //        ATimePrinter.printTime(time, timezone, ps);
-        //        ps.print("\")");
     }
 }
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADurationPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADurationPrinter.java
index 1b141b3..837c3db 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADurationPrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ADurationPrinter.java
@@ -5,6 +5,7 @@
 
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.data.IPrinter;
 import edu.uci.ics.hyracks.algebricks.data.utils.WriteValueTools;
@@ -13,6 +14,7 @@
 
     private static final long serialVersionUID = 1L;
     public static final ADurationPrinter INSTANCE = new ADurationPrinter();
+    private static final GregorianCalendarSystem gCalInstance = GregorianCalendarSystem.getInstance();
 
     @Override
     public void init() {
@@ -25,19 +27,20 @@
         int months = AInt32SerializerDeserializer.getInt(b, s + 1);
         long milliseconds = AInt64SerializerDeserializer.getLong(b, s + 5);
 
+        // set the negative flag. "||" is necessary in case that months field is not there (so it is 0)
         if (months < 0 || milliseconds < 0) {
             months *= -1;
             milliseconds *= -1;
             positive = false;
         }
 
-        int month = (int) (months % 12);
-        int year = (int) (months / 12);
-        int millisecond = (int) (milliseconds % 1000);
-        int second = (int) (milliseconds % 60000 / 1000);
-        int minute = (int) (milliseconds % 3600000 / 60000);
-        int hour = (int) (milliseconds % (86400000) / 3600000);
-        int day = (int) (milliseconds / (86400000));
+        int month = gCalInstance.getDurationMonth(months);
+        int year = gCalInstance.getDurationYear(months);
+        int millisecond = gCalInstance.getDurationMillisecond(milliseconds);
+        int second = gCalInstance.getDurationSecond(milliseconds);
+        int minute = gCalInstance.getDurationMinute(milliseconds);
+        int hour = gCalInstance.getDurationHour(milliseconds);
+        int day = gCalInstance.getDurationDay(milliseconds);
 
         ps.print("duration(\"");
         if (!positive) {
@@ -45,22 +48,37 @@
         }
         try {
             ps.print("P");
-            WriteValueTools.writeInt(year, ps);
-            ps.print("Y");
-            WriteValueTools.writeInt(month, ps);
-            ps.print("M");
-            WriteValueTools.writeInt(day, ps);
-            ps.print("DT");
-            WriteValueTools.writeInt(hour, ps);
-            ps.print("H");
-            WriteValueTools.writeInt(minute, ps);
-            ps.print("M");
-            WriteValueTools.writeInt(second, ps);
+            if (year != 0) {
+                WriteValueTools.writeInt(year, ps);
+                ps.print("Y");
+            }
+            if (month != 0) {
+                WriteValueTools.writeInt(month, ps);
+                ps.print("M");
+            }
+            if (day != 0) {
+                WriteValueTools.writeInt(day, ps);
+                ps.print("D");
+            }
+            if (hour != 0 || minute != 0 || second != 0 || millisecond != 0)
+                ps.print("T");
+            if (hour != 0) {
+                WriteValueTools.writeInt(hour, ps);
+                ps.print("H");
+            }
+            if (minute != 0) {
+                WriteValueTools.writeInt(minute, ps);
+                ps.print("M");
+            }
+            if (second != 0 || millisecond != 0)
+                WriteValueTools.writeInt(second, ps);
             if (millisecond > 0) {
                 ps.print(".");
                 WriteValueTools.writeInt(millisecond, ps);
             }
-            ps.print("S\")");
+            if (second != 0 || millisecond != 0)
+                ps.print("S");
+            ps.print("\")");
         } catch (IOException e) {
             throw new AlgebricksException(e);
         }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ATimePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ATimePrinter.java
index 3bbae4a..bb11ae1 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ATimePrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ATimePrinter.java
@@ -20,14 +20,14 @@
     @Override
     public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
         int time = AInt32SerializerDeserializer.getInt(b, s + 1);
-    	GregorianCalendarSystem calendar = GregorianCalendarSystem.getInstance();        
+        GregorianCalendarSystem calendar = GregorianCalendarSystem.getInstance();
         ps.print("time(\"");
-        
+
         ps.append(String.format("%02d", calendar.getHourOfDay(time))).append(":")
-        .append(String.format("%02d", calendar.getMinOfHour(time))).append(":")
-        .append(String.format("%02d", calendar.getSecOfMin(time))).append(".")
-        .append(String.format("%03d", calendar.getMillisOfSec(time))).append("Z");
-        
+                .append(String.format("%02d", calendar.getMinOfHour(time))).append(":")
+                .append(String.format("%02d", calendar.getSecOfMin(time))).append(".")
+                .append(String.format("%03d", calendar.getMillisOfSec(time))).append("Z");
+
         ps.print("\")");
     }
 
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ATimePrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ATimePrinterFactory.java
index 2603067..afafb89 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ATimePrinterFactory.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ATimePrinterFactory.java
@@ -3,8 +3,6 @@
 import edu.uci.ics.hyracks.algebricks.data.IPrinter;
 import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
 
-
-
 public class ATimePrinterFactory implements IPrinterFactory {
 
     private static final long serialVersionUID = 1L;
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 92019e9..64d8262 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
@@ -7,7 +7,9 @@
 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.GregorianCalendarSystem;
+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;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -16,14 +18,10 @@
 
     private static final long serialVersionUID = 1L;
 
-    private int chrononTimeInDays;
-
     public static final ADateSerializerDeserializer INSTANCE = new ADateSerializerDeserializer();
     @SuppressWarnings("unchecked")
-    private static ISerializerDeserializer<ADate> dateSerde = AqlSerializerDeserializerProvider.INSTANCE
+    private static final ISerializerDeserializer<ADate> dateSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ADATE);
-    private static AMutableDate aDate = new AMutableDate(0);
-    private static final String errorMessage = "This can not be an instance of date";
 
     private ADateSerializerDeserializer() {
     }
@@ -31,8 +29,7 @@
     @Override
     public ADate deserialize(DataInput in) throws HyracksDataException {
         try {
-            chrononTimeInDays = in.readInt();
-            return new ADate(chrononTimeInDays);
+            return new ADate(in.readInt());
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
@@ -48,208 +45,22 @@
     }
 
     public static void parse(String date, DataOutput out) throws HyracksDataException {
-        parseString(date);
-        dateSerde.serialize(aDate, out);
-    }
+        AMutableDate aDate = new AMutableDate(0);
 
-    private static void parseString(String date) throws HyracksDataException {
-        int year = 0, month = 0, day = 0;
-        int timezone = 0;
-        int offset = 0;
-        boolean positive = true;
-        if (date.charAt(offset + 4) == '-' || date.charAt(offset + 5) == '-') {
-            // parse extended form
-            if (date.charAt(offset) == '-') {
-                offset++;
-                positive = false;
-            }
-
-            if (date.charAt(offset + 4) != '-' || date.charAt(offset + 7) != '-')
-                throw new HyracksDataException(errorMessage);
-
-            // year
-            for (int i = 0; i < 4; i++) {
-                if ((date.charAt(offset + i) >= '0' && date.charAt(offset + i) <= '9')) {
-                    year = year * 10 + date.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.YEAR]
-                    || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.YEAR]) {
-                throw new HyracksDataException(errorMessage + ": year " + year);
-            }
-
-            offset += 5;
-
-            // month
-            for (int i = 0; i < 2; i++) {
-                if ((date.charAt(offset + i) >= '0' && date.charAt(offset + i) <= '9')) {
-                    month = month * 10 + date.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MONTH]
-                    || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MONTH]) {
-                throw new HyracksDataException(errorMessage + ": month " + month);
-            }
-
-            offset += 3;
-
-            // day
-            for (int i = 0; i < 2; i++) {
-                if ((date.charAt(offset + i) >= '0' && date.charAt(offset + i) <= '9')) {
-                    day = day * 10 + date.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.DAY]
-                    || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.DAY]) {
-                throw new HyracksDataException(errorMessage + ": day " + day);
-            }
-
-            offset += 2;
-
-            if (!positive)
-                year *= -1;
-
-            if (date.length() > offset) {
-                if (date.charAt(offset) != 'Z') {
-                    if ((date.charAt(offset) != '+' && date.charAt(offset) != '-') || (date.charAt(offset + 3) != ':'))
-                        throw new HyracksDataException(errorMessage);
-
-                    short timezoneHour = 0;
-                    short timezoneMinute = 0;
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((date.charAt(offset + 1 + i) >= '0' && date.charAt(offset + 1 + i) <= '9'))
-                            timezoneHour = (short) (timezoneHour * 10 + date.charAt(offset + 1 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-
-                    }
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((date.charAt(offset + 4 + i) >= '0' && date.charAt(offset + 4 + i) <= '9'))
-                            timezoneMinute = (short) (timezoneMinute * 10 + date.charAt(offset + 4 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-
-                        if (date.charAt(offset) == '-')
-                            timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                        else
-                            timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                    }
-                }
-            }
-
-        } else {
-            // parse basic form
-            if (date.charAt(offset) == '-') {
-                offset++;
-                positive = false;
-            }
-
-            // year
-            for (int i = 0; i < 4; i++) {
-                if ((date.charAt(offset + i) >= '0' && date.charAt(offset + i) <= '9')) {
-                    year = year * 10 + date.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.YEAR]
-                    || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.YEAR]) {
-                throw new HyracksDataException(errorMessage + ": year " + year);
-            }
-
-            offset += 4;
-
-            // month
-            for (int i = 0; i < 2; i++) {
-                if ((date.charAt(offset + i) >= '0' && date.charAt(offset + i) <= '9')) {
-                    month = month * 10 + date.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MONTH]
-                    || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MONTH]) {
-                throw new HyracksDataException(errorMessage + ": month " + month);
-            }
-
-            offset += 2;
-
-            // day
-            for (int i = 0; i < 2; i++) {
-                if ((date.charAt(offset + i) >= '0' && date.charAt(offset + i) <= '9')) {
-                    day = day * 10 + date.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.DAY]
-                    || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.DAY]) {
-                throw new HyracksDataException(errorMessage + ": day " + day);
-            }
-
-            offset += 2;
-
-            if (!positive)
-                year *= -1;
-
-            if (date.length() > offset) {
-                if (date.charAt(offset) != 'Z') {
-                    if ((date.charAt(offset) != '+' && date.charAt(offset) != '-'))
-                        throw new HyracksDataException(errorMessage);
-
-                    short timezoneHour = 0;
-                    short timezoneMinute = 0;
-
-                    for (int i = 0; i < 2; i++) {
-                        if (date.charAt(offset + 1 + i) >= '0' && date.charAt(offset + 1 + i) <= '9')
-                            timezoneHour = (short) (timezoneHour * 10 + date.charAt(offset + 1 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-
-                    }
-
-                    if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-                            || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-                        throw new HyracksDataException(errorMessage + ": time zone hour " + timezoneHour);
-                    }
-
-                    for (int i = 0; i < 2; i++) {
-                        if (date.charAt(offset + 3 + i) >= '0' && date.charAt(offset + 3 + i) <= '9')
-                            timezoneMinute = (short) (timezoneMinute * 10 + date.charAt(offset + 3 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-                    }
-
-                    if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-                            || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-                        throw new HyracksDataException(errorMessage + ": time zone minute " + timezoneMinute);
-                    }
-
-                    if (date.charAt(offset) == '-')
-                        timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                    else
-                        timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                }
-            }
+        long chrononTimeInMs = 0;
+        try {
+            StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
+            charAccessor.reset(date, 0);
+            chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, true);
+        } catch (Exception e) {
+            throw new HyracksDataException(e.getMessage());
         }
 
-        long chrononTimeInMs = GregorianCalendarSystem.getInstance().getChronon(year, month, day, 0, 0, 0, 0, timezone);
-        aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY));
+        short temp = 0;
         if (chrononTimeInMs < 0 && chrononTimeInMs % GregorianCalendarSystem.CHRONON_OF_DAY != 0)
-            aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY) - 1);
+            temp = 1;
+        aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY) - temp);
+
+        dateSerde.serialize(aDate, out);
     }
 }
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 975b9d0..cf92eaa 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
@@ -7,8 +7,10 @@
 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.GregorianCalendarSystem;
+import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+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;
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 
@@ -18,12 +20,10 @@
 
     public static final ADateTimeSerializerDeserializer INSTANCE = new ADateTimeSerializerDeserializer();
     @SuppressWarnings("unchecked")
-    private static ISerializerDeserializer<ADateTime> datetimeSerde = AqlSerializerDeserializerProvider.INSTANCE
+    private static final ISerializerDeserializer<ADateTime> datetimeSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ADATETIME);
-    private static AMutableDateTime aDateTime = new AMutableDateTime(0L);
-    private static final String errorMessage = "This can not be an instance of datetime";
 
-    private long chrononTime;
+    private static final String errorMessage = "This can not be an instance of datetime";
 
     private ADateTimeSerializerDeserializer() {
     }
@@ -31,9 +31,7 @@
     @Override
     public ADateTime deserialize(DataInput in) throws HyracksDataException {
         try {
-            chrononTime = in.readLong();
-
-            return new ADateTime(chrononTime);
+            return new ADateTime(in.readLong());
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
@@ -42,380 +40,39 @@
     @Override
     public void serialize(ADateTime instance, DataOutput out) throws HyracksDataException {
         try {
-            out.writeLong(instance.getChrnonoTime());
+            out.writeLong(instance.getChrononTime());
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
     }
 
     public static void parse(String datetime, DataOutput out) throws HyracksDataException {
-        parseString(datetime);
+        AMutableDateTime aDateTime = new AMutableDateTime(0L);
+
+        long chrononTimeInMs = 0;
+        try {
+            StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
+            charAccessor.reset(datetime, 0);
+
+            // +1 if it is negative (-)
+            short timeOffset = (short) ((charAccessor.getCharAt(0) == '-') ? 1 : 0);
+
+            if (charAccessor.getCharAt(timeOffset + 10) != 'T' && charAccessor.getCharAt(timeOffset + 8) != 'T')
+                throw new AlgebricksException(errorMessage + ": missing T");
+
+            // if extended form 11, else 9
+            timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11) : (short) (9);
+
+            chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, false);
+
+            charAccessor.reset(datetime, timeOffset);
+
+            chrononTimeInMs += ADateAndTimeParser.parseTimePart(charAccessor);
+        } catch (Exception e) {
+            throw new HyracksDataException(e.getMessage());
+        }
+        aDateTime.setValue(chrononTimeInMs);
+
         datetimeSerde.serialize(aDateTime, out);
     }
-
-    private static void parseString(String datetime) throws HyracksDataException {
-        int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0, millis = 0;
-        int timezone = 0;
-
-        int offset = 0;
-
-        boolean positive = true;
-        boolean isExtendedForm = false;
-        if (datetime.charAt(offset + 13) == ':' || datetime.charAt(offset + 14) == ':') {
-            isExtendedForm = true;
-        }
-        if (isExtendedForm) {
-            // parse extended form
-            if (datetime.charAt(offset) == '-') {
-                offset++;
-                positive = false;
-            }
-
-            if (datetime.charAt(offset + 4) != '-' || datetime.charAt(offset + 7) != '-')
-                throw new HyracksDataException(errorMessage);
-
-            // year
-            for (int i = 0; i < 4; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    year = year * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.YEAR]
-                    || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.YEAR]) {
-                throw new HyracksDataException(errorMessage + ": year " + year);
-            }
-
-            offset += 5;
-
-            // month
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    month = month * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MONTH]
-                    || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MONTH]) {
-                throw new HyracksDataException(errorMessage + ": month " + month);
-            }
-
-            offset += 3;
-
-            // day
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    day = day * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.DAY]
-                    || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.DAY]) {
-                throw new HyracksDataException(errorMessage + ": day " + day);
-            }
-
-            offset += 2;
-
-            if (!positive)
-                year *= -1;
-
-            // skip the "T" separator
-            offset += 1;
-
-            if (datetime.charAt(offset + 2) != ':' || datetime.charAt(offset + 5) != ':')
-                throw new HyracksDataException(errorMessage);
-
-            // hour
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    hour = hour * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (hour < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.HOUR]
-                    || hour > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.HOUR]) {
-                throw new HyracksDataException(errorMessage + ": hour " + hour);
-            }
-
-            offset += 3;
-
-            // minute
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    min = min * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (min < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MINUTE]
-                    || min > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MINUTE]) {
-                throw new HyracksDataException(errorMessage + ": min " + min);
-            }
-
-            offset += 3;
-
-            // second
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    sec = sec * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (sec < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.SECOND]
-                    || sec > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.SECOND]) {
-                throw new HyracksDataException(errorMessage + ": sec " + sec);
-            }
-
-            offset += 2;
-
-            if (datetime.length() > offset && datetime.charAt(offset) == '.') {
-
-                offset++;
-                int i = 0;
-                for (; i < 3 && offset + i < datetime.length(); i++) {
-                    if (datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9') {
-                        millis = millis * 10 + datetime.charAt(offset + i) - '0';
-                    } else {
-                        break;
-                    }
-                }
-
-                offset += i;
-
-                for (; i < 3; i++) {
-                    millis = millis * 10;
-                }
-
-                for (; offset < datetime.length(); offset++) {
-                    if (datetime.charAt(offset) < '0' || datetime.charAt(offset) > '9') {
-                        break;
-                    }
-                }
-            }
-
-            if (datetime.length() > offset) {
-                if (datetime.charAt(offset) != 'Z') {
-                    if ((datetime.charAt(offset) != '+' && datetime.charAt(offset) != '-')
-                            || (datetime.charAt(offset + 3) != ':'))
-                        throw new HyracksDataException(errorMessage);
-
-                    short timezoneHour = 0;
-                    short timezoneMinute = 0;
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((datetime.charAt(offset + 1 + i) >= '0' && datetime.charAt(offset + 1 + i) <= '9'))
-                            timezoneHour = (short) (timezoneHour * 10 + datetime.charAt(offset + 1 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-
-                    }
-
-                    if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-                            || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-                        throw new HyracksDataException(errorMessage + ": time zone hour " + timezoneHour);
-                    }
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((datetime.charAt(offset + 4 + i) >= '0' && datetime.charAt(offset + 4 + i) <= '9'))
-                            timezoneMinute = (short) (timezoneMinute * 10 + datetime.charAt(offset + 4 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-                    }
-
-                    if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-                            || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-                        throw new HyracksDataException(errorMessage + ": time zone minute " + timezoneMinute);
-                    }
-
-                    if (datetime.charAt(offset) == '-')
-                        timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                    else
-                        timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                }
-            }
-
-        } else {
-            // parse basic form
-            if (datetime.charAt(offset) == '-') {
-                offset++;
-                positive = false;
-            }
-
-            // year
-            for (int i = 0; i < 4; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    year = year * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.YEAR]
-                    || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.YEAR]) {
-                throw new HyracksDataException(errorMessage + ": year " + year);
-            }
-
-            offset += 4;
-
-            // month
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    month = month * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MONTH]
-                    || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MONTH]) {
-                throw new HyracksDataException(errorMessage + ": month " + month);
-            }
-
-            offset += 2;
-
-            // day
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    day = day * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.DAY]
-                    || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.DAY]) {
-                throw new HyracksDataException(errorMessage + ": day " + day);
-            }
-
-            offset += 2;
-
-            if (!positive)
-                year *= -1;
-
-            // hour
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    hour = hour * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (hour < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.HOUR]
-                    || hour > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.HOUR]) {
-                throw new HyracksDataException(errorMessage + ": hour " + hour);
-            }
-
-            offset += 2;
-
-            // minute
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    min = min * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (min < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MINUTE]
-                    || min > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MINUTE]) {
-                throw new HyracksDataException(errorMessage + ": min " + min);
-            }
-
-            offset += 2;
-
-            // second
-            for (int i = 0; i < 2; i++) {
-                if ((datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9')) {
-                    sec = sec * 10 + datetime.charAt(offset + i) - '0';
-                } else {
-                    throw new HyracksDataException(errorMessage);
-                }
-            }
-
-            if (sec < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.SECOND]
-                    || sec > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.SECOND]) {
-                throw new HyracksDataException(errorMessage + ": sec " + sec);
-            }
-
-            offset += 2;
-
-            if (datetime.length() > offset) {
-                int i = 0;
-                for (; i < 3 && offset + i < datetime.length(); i++) {
-                    if (datetime.charAt(offset + i) >= '0' && datetime.charAt(offset + i) <= '9') {
-                        millis = millis * 10 + datetime.charAt(offset + i) - '0';
-                    } else {
-                        break;
-                    }
-                }
-
-                offset += i;
-
-                for (; i < 3; i++) {
-                    millis = millis * 10;
-                }
-
-                for (; offset < datetime.length(); offset++) {
-                    if (datetime.charAt(offset) < '0' || datetime.charAt(offset) > '9') {
-                        break;
-                    }
-                }
-            }
-
-            if (datetime.length() > offset) {
-                if (datetime.charAt(offset) != 'Z') {
-                    if ((datetime.charAt(offset) != '+' && datetime.charAt(offset) != '-'))
-                        throw new HyracksDataException(errorMessage);
-
-                    short timezoneHour = 0;
-                    short timezoneMinute = 0;
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((datetime.charAt(offset + 1 + i) >= '0' && datetime.charAt(offset + 1 + i) <= '9'))
-                            timezoneHour = (short) (timezoneHour * 10 + datetime.charAt(offset + 1 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-
-                    }
-
-                    if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-                            || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-                        throw new HyracksDataException(errorMessage + ": time zone hour " + timezoneHour);
-                    }
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((datetime.charAt(offset + 3 + i) >= '0' && datetime.charAt(offset + 3 + i) <= '9'))
-                            timezoneMinute = (short) (timezoneMinute * 10 + datetime.charAt(offset + 3 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-                    }
-
-                    if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-                            || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-                        throw new HyracksDataException(errorMessage + ": time zone minute " + timezoneMinute);
-                    }
-
-                    if (datetime.charAt(offset) == '-')
-                        timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                    else
-                        timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                }
-            }
-        }
-
-        aDateTime.setValue(GregorianCalendarSystem.getInstance().getChronon(year, month, day, hour, min, sec,
-                (int) millis, timezone));
-    }
 }
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 77d757a..77d6f28 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,6 +7,8 @@
 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.StringCharSequenceAccessor;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -16,12 +18,9 @@
     private static final long serialVersionUID = 1L;
 
     public static final ADurationSerializerDeserializer INSTANCE = new ADurationSerializerDeserializer();
-
-    private static AMutableDuration aDuration = new AMutableDuration(0, 0);
     @SuppressWarnings("unchecked")
-    private static ISerializerDeserializer<ADuration> durationSerde = AqlSerializerDeserializerProvider.INSTANCE
+    private static final ISerializerDeserializer<ADuration> durationSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ADURATION);
-    private static String errorMessage = " can not be an instance of duration";
 
     private ADurationSerializerDeserializer() {
     }
@@ -47,112 +46,14 @@
 
     public static void parse(String duration, DataOutput out) throws HyracksDataException {
         try {
-            boolean positive = true;
-            int offset = 0;
-            int value = 0, hour = 0, minute = 0, second = 0, millisecond = 0, year = 0, month = 0, day = 0;
-            boolean isYear = true, isMonth = true, isDay = true, isHour = true, isMinute = true, isSecond = true, isMillisecond = true;
-            boolean isTime = false;
-            boolean timeItem = true;
-            if (duration.charAt(offset) == '-') {
-                offset++;
-                positive = false;
-            }
+            AMutableDuration aDuration = new AMutableDuration(0, 0);
+            StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
+            charAccessor.reset(duration, 0);
+            ADurationParser.parse(charAccessor, aDuration);
 
-            if (duration.charAt(offset++) != 'P')
-                throw new HyracksDataException(duration + errorMessage);
-
-            for (; offset < duration.length(); offset++) {
-                if (duration.charAt(offset) >= '0' && duration.charAt(offset) <= '9')
-                    // accumulate the digit fields
-                    value = value * 10 + duration.charAt(offset) - '0';
-                else {
-                    switch (duration.charAt(offset)) {
-                        case 'Y':
-                            if (isYear) {
-                                year = value;
-                                isYear = false;
-                            } else
-                                throw new HyracksDataException(duration + errorMessage);
-                            break;
-                        case 'M':
-                            if (!isTime) {
-                                if (isMonth) {
-                                    month = value;
-                                    isMonth = false;
-                                } else
-                                    throw new HyracksDataException(duration + errorMessage);
-                            } else if (isMinute) {
-                                minute = value;
-                                isMinute = false;
-                                timeItem = false;
-                            } else
-                                throw new HyracksDataException(duration + errorMessage);
-                            break;
-                        case 'D':
-                            if (isDay) {
-                                day = value;
-                                isDay = false;
-                            } else
-                                throw new HyracksDataException(duration + errorMessage);
-                            break;
-                        case 'T':
-                            if (!isTime) {
-                                isTime = true;
-                                timeItem = true;
-                            } else
-                                throw new HyracksDataException(duration + errorMessage);
-                            break;
-
-                        case 'H':
-                            if (isHour) {
-                                hour = value;
-                                isHour = false;
-                                timeItem = false;
-                            } else
-                                throw new HyracksDataException(duration + errorMessage);
-                            break;
-                        case 'S':
-                            if (isSecond) {
-                                second = value;
-                                isSecond = false;
-                                timeItem = false;
-                            } else
-                                throw new HyracksDataException(duration + errorMessage);
-                            break;
-                        case '.':
-                            if (isMillisecond) {
-                                millisecond = value;
-                                isMillisecond = false;
-                                timeItem = false;
-                            } else
-                                throw new HyracksDataException(duration + errorMessage);
-                            break;
-                        default:
-                            throw new HyracksDataException(duration + errorMessage);
-
-                    }
-                    value = 0;
-                }
-            }
-
-            if (isTime && timeItem)
-                throw new HyracksDataException(duration + errorMessage);
-
-            //            if (isYear && isMonth && isDay && !isTime)
-            //                throw new HyracksDataException(duration + errorMessage);
-
-            if (positive)
-                aDuration.setValue(year * 12 + month, day * 24 * 3600 * 1000L + 3600 * 1000L * hour + 60 * minute
-                        * 1000L + second * 1000L + millisecond);
-            else
-                aDuration
-                        .setValue(-1 * (year * 12 + month),
-                                -1
-                                        * (day * 24 * 3600 * 1000L + 3600 * 1000L * hour + 60 * minute * 1000L + second
-                                                * 1000L + millisecond));
             durationSerde.serialize(aDuration, out);
-        } catch (HyracksDataException e) {
-            throw new HyracksDataException(duration + errorMessage);
+        } catch (Exception e) {
+            throw new HyracksDataException(e.getMessage());
         }
     }
 }
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 81f9327..7fe99c3 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,8 @@
 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.GregorianCalendarSystem;
+import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+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;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -19,12 +20,8 @@
     public static final ATimeSerializerDeserializer INSTANCE = new ATimeSerializerDeserializer();
 
     @SuppressWarnings("unchecked")
-    private static ISerializerDeserializer<ATime> timeSerde = AqlSerializerDeserializerProvider.INSTANCE
+    private static final ISerializerDeserializer<ATime> timeSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ATIME);
-    private static AMutableTime aTime = new AMutableTime(0);
-    private static String errorMessage = "This can not be an instance of time";
-
-    private int ora;
 
     private ATimeSerializerDeserializer() {
     }
@@ -32,9 +29,8 @@
     @Override
     public ATime deserialize(DataInput in) throws HyracksDataException {
         try {
-            ora = in.readInt();
+            return new ATime(in.readInt());
 
-            return new ATime(ora);
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
@@ -43,7 +39,7 @@
     @Override
     public void serialize(ATime instance, DataOutput out) throws HyracksDataException {
         try {
-            out.writeInt(instance.getOra());
+            out.writeInt(instance.getChrononTime());
 
         } catch (IOException e) {
             throw new HyracksDataException(e);
@@ -51,237 +47,20 @@
     }
 
     public static void parse(String time, DataOutput out) throws HyracksDataException {
-        parseString(time);
+        AMutableTime aTime = new AMutableTime(0);
+        int chrononTimeInMs;
+
+        try {
+            StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
+            charAccessor.reset(time, 0);
+            chrononTimeInMs = ADateAndTimeParser.parseTimePart(charAccessor);
+        } catch (Exception e) {
+            throw new HyracksDataException(e.getMessage());
+        }
+
+        aTime.setValue(chrononTimeInMs);
+
         timeSerde.serialize(aTime, out);
     }
 
-    private static void parseString(String time) throws HyracksDataException {
-
-        int hour = 0, min = 0, sec = 0, millis = 0;
-        int timezone = 0;
-
-        int offset = 0;
-
-        boolean isExtendedForm = false;
-        if (time.charAt(offset + 2) == ':') {
-            isExtendedForm = true;
-        }
-        if (isExtendedForm) {
-            // parse extended form
-            if (time.charAt(offset) == '-' || time.charAt(offset + 5) != ':')
-                throw new HyracksDataException(errorMessage);
-
-            for (int i = 0; i < 2; i++) {
-                if ((time.charAt(offset + i) >= '0' && time.charAt(offset + i) <= '9'))
-                    hour = hour * 10 + time.charAt(offset + i) - '0';
-                else
-                    throw new HyracksDataException(errorMessage);
-
-            }
-
-            if (hour < 0 || hour > 23) {
-                throw new HyracksDataException(errorMessage + ": hour " + hour);
-            }
-
-            offset += 3;
-
-            for (int i = 0; i < 2; i++) {
-                if ((time.charAt(offset + i) >= '0' && time.charAt(offset + i) <= '9'))
-                    min = min * 10 + time.charAt(offset + i) - '0';
-                else
-                    throw new HyracksDataException(errorMessage);
-
-            }
-
-            if (min < 0 || min > 59) {
-                throw new HyracksDataException(errorMessage + ": min " + min);
-            }
-
-            offset += 3;
-
-            for (int i = 0; i < 2; i++) {
-                if ((time.charAt(offset + i) >= '0' && time.charAt(offset + i) <= '9'))
-                    sec = sec * 10 + time.charAt(offset + i) - '0';
-                else
-                    throw new HyracksDataException(errorMessage);
-
-            }
-
-            if (sec < 0 || sec > 59) {
-                throw new HyracksDataException(errorMessage + ": sec " + sec);
-            }
-
-            offset += 2;
-
-            if (time.length() > offset && time.charAt(offset) == '.') {
-
-                offset++;
-                int i = 0;
-                for (; i < 3 && offset + i < time.length(); i++) {
-                    if (time.charAt(offset + i) >= '0' && time.charAt(offset + i) <= '9') {
-                        millis = millis * 10 + time.charAt(offset + i) - '0';
-                    } else {
-                        break;
-                    }
-                }
-
-                offset += i;
-
-                for (; i < 3; i++) {
-                    millis = millis * 10;
-                }
-
-                for (; offset < time.length(); offset++) {
-                    if (time.charAt(offset) < '0' || time.charAt(offset) > '9') {
-                        break;
-                    }
-                }
-            }
-
-            if (time.length() > offset) {
-                if (time.charAt(offset) != 'Z') {
-                    if ((time.charAt(offset) != '+' && time.charAt(offset) != '-') || (time.charAt(offset + 3) != ':'))
-                        throw new HyracksDataException(errorMessage);
-
-                    short timezoneHour = 0;
-                    short timezoneMinute = 0;
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((time.charAt(offset + 1 + i) >= '0' && time.charAt(offset + 1 + i) <= '9'))
-                            timezoneHour = (short) (timezoneHour * 10 + time.charAt(offset + 1 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-
-                    }
-
-                    if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-                            || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-                        throw new HyracksDataException(errorMessage + ": time zone hour " + timezoneHour);
-                    }
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((time.charAt(offset + 4 + i) >= '0' && time.charAt(offset + 4 + i) <= '9'))
-                            timezoneMinute = (short) (timezoneMinute * 10 + time.charAt(offset + 4 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-                    }
-
-                    if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-                            || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-                        throw new HyracksDataException(errorMessage + ": time zone minute " + timezoneMinute);
-                    }
-
-                    if (time.charAt(offset) == '-')
-                        timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                    else
-                        timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                }
-            }
-
-        } else {
-            // parse basic form
-
-            if (time.charAt(offset) == '-')
-                throw new HyracksDataException(errorMessage);
-
-            for (int i = 0; i < 2; i++) {
-                if ((time.charAt(offset + i) >= '0' && time.charAt(offset + i) <= '9'))
-                    hour = hour * 10 + time.charAt(offset + i) - '0';
-                else
-                    throw new HyracksDataException(errorMessage);
-
-            }
-
-            if (hour < 0 || hour > 23) {
-                throw new HyracksDataException(errorMessage + ": hour " + hour);
-            }
-
-            offset += 2;
-
-            for (int i = 0; i < 2; i++) {
-                if ((time.charAt(offset + i) >= '0' && time.charAt(offset + i) <= '9'))
-                    min = min * 10 + time.charAt(offset + i) - '0';
-                else
-                    throw new HyracksDataException(errorMessage);
-
-            }
-
-            if (min < 0 || min > 59) {
-                throw new HyracksDataException(errorMessage + ": min " + min);
-            }
-
-            offset += 2;
-
-            for (int i = 0; i < 2; i++) {
-                if ((time.charAt(offset + i) >= '0' && time.charAt(offset + i) <= '9'))
-                    sec = sec * 10 + time.charAt(offset + i) - '0';
-                else
-                    throw new HyracksDataException(errorMessage);
-
-            }
-
-            if (sec < 0 || sec > 59) {
-                throw new HyracksDataException(errorMessage + ": sec " + sec);
-            }
-
-            offset += 2;
-
-            if (time.length() > offset) {
-                int i = 0;
-                for (; i < 3 && offset + i < time.length(); i++) {
-                    if ((time.charAt(offset + i) >= '0' && time.charAt(offset + i) <= '9')) {
-                        millis = millis * 10 + time.charAt(offset + i) - '0';
-                    } else {
-                        break;
-                    }
-                }
-
-                offset += i;
-
-                for (; i < 3; i++) {
-                    millis = millis * 10;
-                }
-
-                for (; offset < time.length(); offset++) {
-                    if (time.charAt(offset) < '0' || time.charAt(offset) > '9') {
-                        break;
-                    }
-                }
-            }
-
-            if (time.length() > offset) {
-                if (time.charAt(offset) != 'Z') {
-                    if ((time.charAt(offset) != '+' && time.charAt(offset) != '-'))
-                        throw new HyracksDataException(errorMessage);
-
-                    short timezoneHour = 0;
-                    short timezoneMinute = 0;
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((time.charAt(offset + 1 + i) >= '0' && time.charAt(offset + 1 + i) <= '9'))
-                            timezoneHour = (short) (timezoneHour * 10 + time.charAt(offset + 1 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-
-                    }
-
-                    for (int i = 0; i < 2; i++) {
-                        if ((time.charAt(offset + 3 + i) >= '0' && time.charAt(offset + 3 + i) <= '9'))
-                            timezoneMinute = (short) (timezoneMinute * 10 + time.charAt(offset + 3 + i) - '0');
-                        else
-                            throw new HyracksDataException(errorMessage);
-
-                    }
-
-                    if (time.charAt(offset) == '-')
-                        timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                    else
-                        timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                }
-            }
-        }
-
-        aTime.setValue(GregorianCalendarSystem.getInstance().getChronon(hour, min, sec, millis, timezone));
-
-    }
 }
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADate.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADate.java
index 0eefc98..06d2a96 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADate.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADate.java
@@ -11,6 +11,9 @@
  */
 public class ADate implements IAObject {
 
+    /**
+     * the number of full calendar days since the 1970-01-01 represented by the date value.
+     */
     protected int chrononTimeInDay;
 
     private static long CHRONON_OF_DAY = 24 * 60 * 60 * 1000;
@@ -56,7 +59,7 @@
         StringBuilder sbder = new StringBuilder();
         sbder.append("ADate: { ");
         GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(
-                chrononTimeInDay * CHRONON_OF_DAY, 0, sbder, GregorianCalendarSystem.YEAR, GregorianCalendarSystem.DAY);
+                chrononTimeInDay * CHRONON_OF_DAY, 0, sbder, GregorianCalendarSystem.Fields.YEAR, GregorianCalendarSystem.Fields.DAY);
         sbder.append(" }");
         return sbder.toString();
     }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADateTime.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADateTime.java
index a410bed..38835cf 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADateTime.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADateTime.java
@@ -90,12 +90,12 @@
         StringBuilder sbder = new StringBuilder();
         sbder.append("ADateTime: { ");
         GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(chrononTime, 0, sbder,
-                GregorianCalendarSystem.YEAR, GregorianCalendarSystem.MILLISECOND);
+                GregorianCalendarSystem.Fields.YEAR, GregorianCalendarSystem.Fields.MILLISECOND);
         sbder.append(" }");
         return sbder.toString();
     }
 
-    public long getChrnonoTime() {
+    public long getChrononTime() {
         return chrononTime;
     }
 
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADuration.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADuration.java
index 7c60822..1f9044b 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADuration.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADuration.java
@@ -1,13 +1,40 @@
 package edu.uci.ics.asterix.om.base;
 
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.asterix.om.visitors.IOMVisitor;
 
+/**
+ * ADuration type represents time duration (unanchored time length) values.
+ * <p/>
+ * An ADuration value may contain the same fields as the {@link ADateTime}: <br/>
+ * - year;<br/>
+ * - month;<br/>
+ * - day;<br/>
+ * - hour; <br/>
+ * - minute; <br/>
+ * - second; <br/>
+ * - millisecond. <br/>
+ * Compared with {@link ADateTime}, a field in a duration value does not have the limited domain requirement. A duration field is valid as far as the value of the field is an integer.
+ * </p>
+ * We also support negative durations, which is not specified by ISO 8601, but has been
+ * supported by XML spec to enable the arithmetic operations between time instances.
+ * <p/>
+ * Internally, an ADuration value is stored as two fields: an integer field as the number of months for the YEAR and MONTH fields, and a long integer field as the number of milliseconds for the other fields.
+ * <p/>
+ */
 public class ADuration implements IAObject {
 
+    /**
+     * number of full months represented by the year-month part
+     */
     protected int chrononInMonth;
+
+    /**
+     * number of milliseconds represented by the part other than the year and month
+     */
     protected long chrononInMillisecond;
 
     public ADuration(int months, long seconds) {
@@ -58,4 +85,13 @@
         return hashCode();
     }
 
+    @Override
+    public String toString() {
+        StringBuilder sbder = new StringBuilder();
+        sbder.append("ADuration: {");
+        GregorianCalendarSystem.getInstance().getDurationExtendStringRepWithTimezoneUntilField(chrononInMillisecond, chrononInMonth, sbder);
+        sbder.append(" }");
+        return sbder.toString();
+    }
+
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableTime.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableTime.java
index 277479f..d6b7858 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableTime.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableTime.java
@@ -2,12 +2,12 @@
 
 public class AMutableTime extends ATime {
 
-    public AMutableTime(int ora) {
-        super(ora);
+    public AMutableTime(int timeInMillisec) {
+        super(timeInMillisec);
     }
 
-    public void setValue(int ora) {
-        this.chrononTime = ora;
+    public void setValue(int timeInMillisec) {
+        this.chrononTime = timeInMillisec;
     }
 
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ATime.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ATime.java
index 7f6cc1e..0ce7d99 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ATime.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ATime.java
@@ -8,10 +8,13 @@
 
 public class ATime implements IAObject {
 
+    /**
+     * number of milliseconds since the beginning of a day represented by this time value
+     */
     protected int chrononTime;
 
-    public ATime(int ora) {
-        this.chrononTime = ora;
+    public ATime(int chrononTime) {
+        this.chrononTime = chrononTime;
     }
 
     @Override
@@ -71,13 +74,13 @@
         StringBuilder sbder = new StringBuilder();
         sbder.append("ATime: { ");
         GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(chrononTime, 0, sbder,
-                GregorianCalendarSystem.HOUR, GregorianCalendarSystem.MILLISECOND);
+                GregorianCalendarSystem.Fields.HOUR, GregorianCalendarSystem.Fields.MILLISECOND);
         sbder.append(" }");
         return sbder.toString();
 
     }
 
-    public int getOra() {
+    public int getChrononTime() {
         return chrononTime;
     }
 
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
new file mode 100644
index 0000000..28eb898
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateAndTimeParser.java
@@ -0,0 +1,244 @@
+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(dateErrorMessage);
+
+        // 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(dateErrorMessage);
+            }
+        }
+
+        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(dateErrorMessage);
+            }
+        }
+
+        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(dateErrorMessage);
+            }
+        }
+
+        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(dateErrorMessage);
+        }
+        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(timeErrorMessage);
+
+        // 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(timeErrorMessage);
+            }
+        }
+
+        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(timeErrorMessage);
+            }
+        }
+
+        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(timeErrorMessage);
+            }
+        }
+
+        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.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(timeErrorMessage);
+
+                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(timeErrorMessage);
+
+                }
+
+                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(timeErrorMessage);
+                }
+
+                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 gCalInstance.getChronon(hour, min, sec, millis, timezone);
+    }
+}
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/ADurationParser.java
new file mode 100644
index 0000000..c6bed37
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParser.java
@@ -0,0 +1,125 @@
+package edu.uci.ics.asterix.om.base.temporal;
+
+import edu.uci.ics.asterix.om.base.AMutableDuration;
+
+public class ADurationParser {
+
+    private enum State {
+        NOTHING_READ,
+        YEAR,
+        MONTH,
+        DAY,
+        TIME,
+        HOUR,
+        MIN,
+        MILLISEC,
+        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 {
+
+        boolean positive = true;
+        int offset = 0;
+        int value = 0, hour = 0, minute = 0, second = 0, millisecond = 0, year = 0, month = 0, day = 0;
+        State state = State.NOTHING_READ;
+
+        if (charAccessor.getCharAt(offset) == '-') {
+            offset++;
+            positive = false;
+        }
+
+        if (charAccessor.getCharAt(offset++) != 'P')
+            throw new Exception(errorMessage);
+
+        for (; offset < charAccessor.getLength(); offset++) {
+            if (charAccessor.getCharAt(offset) >= '0' && charAccessor.getCharAt(offset) <= '9')
+                // accumulate the digit fields
+                value = value * 10 + charAccessor.getCharAt(offset) - '0';
+            else {
+                switch (charAccessor.getCharAt(offset)) {
+                    case 'Y':
+                        if (state.compareTo(State.YEAR) < 0) {
+                            year = value;
+                            state = State.YEAR;
+                        } else
+                            throw new Exception(errorMessage);
+                        break;
+                    case 'M':
+                        if (state.compareTo(State.TIME) < 0) {
+                            if (state.compareTo(State.MONTH) < 0) {
+                                month = value;
+                                state = State.MONTH;
+                            } else
+                                throw new Exception(errorMessage);
+                        } else if (state.compareTo(State.MIN) < 0) {
+                            minute = value;
+                            state = State.MIN;
+                        } else
+                            throw new Exception(errorMessage);
+                        break;
+                    case 'D':
+                        if (state.compareTo(State.DAY) < 0) {
+                            day = value;
+                            state = State.DAY;
+                        } else
+                            throw new Exception(errorMessage);
+                        break;
+                    case 'T':
+                        if (state.compareTo(State.TIME) < 0) {
+                            state = State.TIME;
+                        } else
+                            throw new Exception(errorMessage);
+                        break;
+
+                    case 'H':
+                        if (state.compareTo(State.HOUR) < 0) {
+                            hour = value;
+                            state = State.HOUR;
+                        } else
+                            throw new Exception(errorMessage);
+                        break;
+                    case '.':
+                        if (state.compareTo(State.MILLISEC) < 0) {
+                            int i = 1;
+                            for (; offset + i < charAccessor.getLength(); i++) {
+                                if (charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9') {
+                                    if (i < 4)
+                                        millisecond = millisecond * 10 + (charAccessor.getCharAt(offset + i) - '0');
+                                    else
+                                        throw new Exception(errorMessage);
+                                } else
+                                    break;
+                            }
+                            offset += i;
+                            state = State.MILLISEC;
+                        } else
+                            throw new Exception(errorMessage);
+                    case 'S':
+                        if (state.compareTo(State.SEC) < 0) {
+                            second = value;
+                            state = State.SEC;
+                        } else
+                            throw new Exception(errorMessage);
+                        break;
+                    default:
+                        throw new Exception(errorMessage);
+
+                }
+                value = 0;
+            }
+        }
+
+        if (state.compareTo(State.TIME) == 0)
+            throw new Exception(errorMessage);
+
+        short temp = 1;
+        if (!positive)
+            temp = -1;
+
+        aDuration.setValue(temp * (year * 12 + month), temp
+                * (day * 24 * 3600 * 1000L + 3600 * 1000L * hour + 60 * minute * 1000L + second * 1000L + millisecond));
+
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ByteArrayCharSequenceAccessor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ByteArrayCharSequenceAccessor.java
new file mode 100644
index 0000000..cae6275
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ByteArrayCharSequenceAccessor.java
@@ -0,0 +1,26 @@
+package edu.uci.ics.asterix.om.base.temporal;
+
+public class ByteArrayCharSequenceAccessor implements ICharSequenceAccessor<Byte[]> {
+
+    private byte[] string;
+    private int offset;
+    private int beginOffset;
+
+    @Override
+    public char getCharAt(int index) {
+        return (char) (string[index + offset + beginOffset]);
+    }
+
+    /* The offset is the position of the first letter in the byte array */
+    public void reset(byte[] obj, int beginOffset, int offset) {
+        string = obj;
+        this.offset = offset;
+        this.beginOffset = beginOffset;
+    }
+
+    @Override
+    public int getLength() {
+        return ((string[beginOffset - 2] & 0xff) << 8) + ((string[beginOffset - 1] & 0xff) << 0) - offset;
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
index 288cd53..0655ccf 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
@@ -36,7 +36,17 @@
  */
 public class GregorianCalendarSystem implements ICalendarSystem {
 
-    public static final int YEAR = 0, MONTH = 1, DAY = 2, HOUR = 3, MINUTE = 4, SECOND = 5, MILLISECOND = 6;
+    public enum Fields {
+        YEAR,
+        MONTH,
+        DAY,
+        HOUR,
+        MINUTE,
+        SECOND,
+        MILLISECOND
+    };
+
+    //public static final int YEAR = 0, MONTH = 1, DAY = 2, HOUR = 3, MINUTE = 4, SECOND = 5, MILLISECOND = 6;
 
     public static final int[] DAYS_OF_MONTH_ORDI = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
     public static final int[] DAYS_OF_MONTH_LEAP = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
@@ -128,6 +138,13 @@
 
     /**
      * Check whether the given time zone value is a valid time zone following the gregorian calendar system.
+     * <p/>
+     * The valid timezone is within the range of:<br/>
+     * - Hours: UTC -12 (Y, or Yankee Time Zone) to UTC +14 (LINT, or Line Islands Time) <br/>
+     * - Minutes: currently the available minutes include 00, 30 and 45.
+     * <p/>
+     * Reference: http://www.timeanddate.com/library/abbreviations/timezones/
+     * <p/>
      * 
      * @param timezone
      * @return
@@ -206,9 +223,9 @@
      */
     public int getChronon(int hour, int min, int sec, int millis, int timezone) {
         // Added milliseconds for all fields but month and day
-        int ora = (hour - timezone / 4) * CHRONON_OF_HOUR + (min - (timezone % 4) * 15) * CHRONON_OF_MINUTE + sec
-                * CHRONON_OF_SECOND + millis;
-        return ora;
+        int chrononTime = (hour - timezone / 4) * CHRONON_OF_HOUR + (min - (timezone % 4) * 15) * CHRONON_OF_MINUTE
+                + sec * CHRONON_OF_SECOND + millis;
+        return chrononTime;
     }
 
     /**
@@ -224,7 +241,7 @@
      * @param untilField
      */
     public void getExtendStringRepWithTimezoneUntilField(long chrononTime, int timezone, StringBuilder sbder,
-            int startField, int untilField) {
+            Fields startField, Fields untilField) {
 
         int year = getYear(chrononTime);
         int month = getMonthOfYear(chrononTime, year);
@@ -232,39 +249,39 @@
         switch (startField) {
             case YEAR:
                 sbder.append(String.format(year < 0 ? "%05d" : "%04d", year));
-                if (untilField == YEAR) {
+                if (untilField == Fields.YEAR) {
                     return;
                 }
             case MONTH:
-                if (startField != MONTH)
+                if (startField != Fields.MONTH)
                     sbder.append("-");
                 sbder.append(String.format("%02d", month));
-                if (untilField == MONTH) {
+                if (untilField == Fields.MONTH) {
                     return;
                 }
             case DAY:
-                if (startField != DAY)
+                if (startField != Fields.DAY)
                     sbder.append("-");
                 sbder.append(String.format("%02d", getDayOfMonthYear(chrononTime, year, month)));
-                if (untilField == DAY) {
+                if (untilField == Fields.DAY) {
                     break;
                 }
             case HOUR:
-                if (startField != HOUR)
+                if (startField != Fields.HOUR)
                     sbder.append("T");
                 sbder.append(String.format("%02d", getHourOfDay(chrononTime)));
-                if (untilField == HOUR) {
+                if (untilField == Fields.HOUR) {
                     break;
                 }
             case MINUTE:
-                if (startField != MINUTE)
+                if (startField != Fields.MINUTE)
                     sbder.append(":");
                 sbder.append(String.format("%02d", getMinOfHour(chrononTime)));
-                if (untilField == MINUTE) {
+                if (untilField == Fields.MINUTE) {
                     break;
                 }
             case SECOND:
-                if (startField != SECOND)
+                if (startField != Fields.SECOND)
                     sbder.append(":");
                 sbder.append(String.format("%02d", getSecOfMin(chrononTime)));
                 // add millisecond as the precision fields of a second
@@ -272,7 +289,7 @@
                 break;
         }
 
-        if (timezone == 0) {
+        if (untilField.compareTo(Fields.DAY) > 0) {
             sbder.append("Z");
         } else {
             short tzMin = (short) ((timezone % 4) * 15);
@@ -289,35 +306,35 @@
      * @param timezone
      * @param sbder
      */
-    public void getBasicStringRepWithTimezoneUntiField(long chrononTime, int timezone, StringBuilder sbder,
-            int startField, int untilField) {
+    public void getBasicStringRepWithTimezoneUntilField(long chrononTime, int timezone, StringBuilder sbder,
+            Fields startField, Fields untilField) {
         int year = getYear(chrononTime);
         int month = getMonthOfYear(chrononTime, year);
 
         switch (startField) {
             case YEAR:
                 sbder.append(String.format(year < 0 ? "%05d" : "%04d", year));
-                if (untilField == YEAR) {
+                if (untilField == Fields.YEAR) {
                     return;
                 }
             case MONTH:
                 sbder.append(String.format("%02d", month));
-                if (untilField == MONTH) {
+                if (untilField == Fields.MONTH) {
                     return;
                 }
             case DAY:
                 sbder.append(String.format("%02d", getDayOfMonthYear(chrononTime, year, month)));
-                if (untilField == DAY) {
+                if (untilField == Fields.DAY) {
                     break;
                 }
             case HOUR:
                 sbder.append(String.format("%02d", getHourOfDay(chrononTime)));
-                if (untilField == HOUR) {
+                if (untilField == Fields.HOUR) {
                     break;
                 }
             case MINUTE:
                 sbder.append(String.format("%02d", getMinOfHour(chrononTime)));
-                if (untilField == MINUTE) {
+                if (untilField == Fields.MINUTE) {
                     break;
                 }
             case SECOND:
@@ -327,7 +344,7 @@
                 break;
         }
 
-        if (timezone == 0) {
+        if (untilField.compareTo(Fields.DAY) > 0) {
             sbder.append("Z");
         } else {
             short tzMin = (short) ((timezone % 4) * 15);
@@ -338,6 +355,52 @@
     }
 
     /**
+     * Get the extended string representation of the given months and milliseconds (duration) time. *
+     * <p/>
+     * The extended and simple string representation is like:<br/>
+     * [-]PnYnMnDTnHnMnS
+     * 
+     * @param milliseconds
+     * @param months
+     * @param sbder
+     */
+
+    public void getDurationExtendStringRepWithTimezoneUntilField(long milliseconds, int months, StringBuilder sbder) {
+
+        boolean positive = true;
+
+        // set the negative flag. "||" is necessary in case that months field is not there (so it is 0)
+        if (months < 0 || milliseconds < 0) {
+            months *= -1;
+            milliseconds *= -1;
+            positive = false;
+        }
+
+        int month = getDurationMonth(months);
+        int year = getDurationYear(months);
+        int millisecond = getDurationMillisecond(milliseconds);
+        int second = getDurationSecond(milliseconds);
+        int minute = getDurationMinute(milliseconds);
+        int hour = getDurationHour(milliseconds);
+        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 : "");
+        if (millisecond > 0)
+            sbder.append("." + millisecond);
+        sbder.append((second != 0 || millisecond != 0) ? "S" : "");
+    }
+
+    /**
      * Check whether a given year is a leap year.
      * 
      * @param year
@@ -443,71 +506,69 @@
         // There are 86400000 milliseconds per day, but divided by 1024 is
         // 84375. There are 84375 (128/125)seconds per day.
 
-        
-//    	if (isleap_year==true)
-//    		if (i < 182 * 84375 /*Days before the end of June*/)
-//    			if (i < 91 * 84375 /*Days before the end of March*/)
-//    				if (i < 31 * 84375 /*Days before the end of January*/)
-//    					Month is 1
-//    				else if (i < 60 * 84375 /*Days before the end of February of leap year*/)
-//    					Month is 2
-//    				else
-//    					Month is 3
-//    			else
-//    				if (i < 121 * 84375 /*Days before the end of April*/)
-//    					Month is 4
-//    				else if (i < 152 * 84375 /*Days before the end of May*/)
-//    					Month is 5
-//    				else
-//    					Month is 6
-//    		else
-//    			if (i < 274 * 84375 /*Days before the end of September*/)
-//    				if (i < 213 * 84375 /*Days before the end of July*/)
-//    					Month is 7
-//    				else if (i < 244 * 84375 /*Days before the end of August*/)
-//    					Month is 8
-//    				else
-//    					Month is 9
-//    			else
-//    				if (i < 305 * 84375 /*Days before the end of October*/)
-//    					Month is 10
-//    				else if (i < 335 * 84375 /*Days before the end of November*/)
-//    					Month is 11
-//    				else
-//    					Month is 12
-//    	else /*Not a leap year*/
-//    		if (i < 181 * 84375 /*Days before the end of June*/)
-//    			if (i < 90 * 84375 /*Days before the end of March*/)
-//    				if (i < 31 * 84375 /*Days before the end of January*/)
-//    					Month is 1
-//    				else if (i < 59 * 84375 /*Days before the end of February of NON leap year*/)
-//    					Month is 2
-//    				else
-//    					Month is 3
-//    			else
-//    				if (i < 120 * 84375 /*Days before the end of April*/)
-//    					Month is 4
-//    				else if (i < 151 * 84375 /*Days before the end of May*/)
-//    					Month is 5
-//    				else
-//    					Month is 6
-//    		else
-//    			if (i < 273 * 84375 /*Days before the end of September*/)
-//    				if (i < 213 * 84375 /*Days before the end of July*/)
-//    					Month is 7
-//    				else if (i < 243 * 84375 /*Days before the end of August*/)
-//    					Month is 8
-//    				else
-//    					Month is 9
-//    			else
-//    				if (i < 304 * 84375 /*Days before the end of October*/)
-//    					Month is 10
-//    				else if (i < 334 * 84375 /*Days before the end of November*/)
-//    					Month is 11
-//    				else
-//    					Month is 12
-        
-        
+        //    	if (isleap_year==true)
+        //    		if (i < 182 * 84375 /*Days before the end of June*/)
+        //    			if (i < 91 * 84375 /*Days before the end of March*/)
+        //    				if (i < 31 * 84375 /*Days before the end of January*/)
+        //    					Month is 1
+        //    				else if (i < 60 * 84375 /*Days before the end of February of leap year*/)
+        //    					Month is 2
+        //    				else
+        //    					Month is 3
+        //    			else
+        //    				if (i < 121 * 84375 /*Days before the end of April*/)
+        //    					Month is 4
+        //    				else if (i < 152 * 84375 /*Days before the end of May*/)
+        //    					Month is 5
+        //    				else
+        //    					Month is 6
+        //    		else
+        //    			if (i < 274 * 84375 /*Days before the end of September*/)
+        //    				if (i < 213 * 84375 /*Days before the end of July*/)
+        //    					Month is 7
+        //    				else if (i < 244 * 84375 /*Days before the end of August*/)
+        //    					Month is 8
+        //    				else
+        //    					Month is 9
+        //    			else
+        //    				if (i < 305 * 84375 /*Days before the end of October*/)
+        //    					Month is 10
+        //    				else if (i < 335 * 84375 /*Days before the end of November*/)
+        //    					Month is 11
+        //    				else
+        //    					Month is 12
+        //    	else /*Not a leap year*/
+        //    		if (i < 181 * 84375 /*Days before the end of June*/)
+        //    			if (i < 90 * 84375 /*Days before the end of March*/)
+        //    				if (i < 31 * 84375 /*Days before the end of January*/)
+        //    					Month is 1
+        //    				else if (i < 59 * 84375 /*Days before the end of February of NON leap year*/)
+        //    					Month is 2
+        //    				else
+        //    					Month is 3
+        //    			else
+        //    				if (i < 120 * 84375 /*Days before the end of April*/)
+        //    					Month is 4
+        //    				else if (i < 151 * 84375 /*Days before the end of May*/)
+        //    					Month is 5
+        //    				else
+        //    					Month is 6
+        //    		else
+        //    			if (i < 273 * 84375 /*Days before the end of September*/)
+        //    				if (i < 213 * 84375 /*Days before the end of July*/)
+        //    					Month is 7
+        //    				else if (i < 243 * 84375 /*Days before the end of August*/)
+        //    					Month is 8
+        //    				else
+        //    					Month is 9
+        //    			else
+        //    				if (i < 304 * 84375 /*Days before the end of October*/)
+        //    					Month is 10
+        //    				else if (i < 334 * 84375 /*Days before the end of November*/)
+        //    					Month is 11
+        //    				else
+        //    					Month is 12
+
         return (isLeapYear(year)) ? ((i < 182 * 84375) ? ((i < 91 * 84375) ? ((i < 31 * 84375) ? 1
                 : (i < 60 * 84375) ? 2 : 3) : ((i < 121 * 84375) ? 4 : (i < 152 * 84375) ? 5 : 6))
                 : ((i < 274 * 84375) ? ((i < 213 * 84375) ? 7 : (i < 244 * 84375) ? 8 : 9) : ((i < 305 * 84375) ? 10
@@ -614,4 +675,32 @@
         }
         return ms;
     }
+
+    public int getDurationMonth(int months) {
+        return (months % 12);
+    }
+
+    public int getDurationYear(int months) {
+        return (months / 12);
+    }
+
+    public int getDurationMillisecond(long milliseconds) {
+        return (int) (milliseconds % 1000);
+    }
+
+    public int getDurationSecond(long milliseconds) {
+        return (int) ((milliseconds % 60000) / 1000);
+    }
+
+    public int getDurationMinute(long milliseconds) {
+        return (int) ((milliseconds % 3600000) / 60000);
+    }
+
+    public int getDurationHour(long milliseconds) {
+        return (int) ((milliseconds % (86400000)) / 3600000);
+    }
+
+    public int getDurationDay(long milliseconds) {
+        return (int) (milliseconds / (86400000));
+    }
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICalendarSystem.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICalendarSystem.java
index 410b73a..be9545d 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICalendarSystem.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICalendarSystem.java
@@ -1,15 +1,47 @@
 package edu.uci.ics.asterix.om.base.temporal;
 
-import java.io.DataOutput;
-
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-
 public interface ICalendarSystem {
 
+    /**
+     * check whether the given time stamp is valid in the calendar system.
+     * 
+     * @param year
+     * @param month
+     * @param day
+     * @param hour
+     * @param min
+     * @param sec
+     * @param millis
+     * @param timezone
+     * @return
+     */
     public boolean validate(int year, int month, int day, int hour, int min, int sec, int millis, int timezone);
 
+    /**
+     * get the chronon time for the given time stamp in the calendar system.
+     * 
+     * @param year
+     * @param month
+     * @param day
+     * @param hour
+     * @param min
+     * @param sec
+     * @param millis
+     * @param timezone
+     * @return
+     */
     public long getChronon(int year, int month, int day, int hour, int min, int sec, int millis, int timezone);
 
+    /**
+     * get the chronon time for the given time in the calendar system
+     * 
+     * @param hour
+     * @param min
+     * @param sec
+     * @param millis
+     * @param timezone
+     * @return
+     */
     public int getChronon(int hour, int min, int sec, int millis, int timezone);
 
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICharSequenceAccessor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICharSequenceAccessor.java
new file mode 100644
index 0000000..a04c04f
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICharSequenceAccessor.java
@@ -0,0 +1,9 @@
+package edu.uci.ics.asterix.om.base.temporal;
+
+public interface ICharSequenceAccessor<T> {
+
+    public char getCharAt(int index);
+
+    public int getLength();
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/StringCharSequenceAccessor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/StringCharSequenceAccessor.java
new file mode 100644
index 0000000..6439db8
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/StringCharSequenceAccessor.java
@@ -0,0 +1,23 @@
+package edu.uci.ics.asterix.om.base.temporal;
+
+public class StringCharSequenceAccessor implements ICharSequenceAccessor<String> {
+
+    private String string;
+    private int offset;
+
+    @Override
+    public char getCharAt(int index) {
+        return string.charAt(index + offset);
+    }
+
+    public void reset(String obj, int offset) {
+        string = obj;
+        this.offset = offset;
+    }
+
+    @Override
+    public int getLength() {
+        return string.length() - offset;
+    }
+
+}
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 3a28805..148dcb9 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
@@ -8,6 +8,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.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;
@@ -29,6 +31,9 @@
     public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "date", 1, false);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+    private final static ByteArrayCharSequenceAccessor charAccessor = new ByteArrayCharSequenceAccessor();
+
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
             return new ADateConstructorDescriptor();
@@ -48,7 +53,6 @@
 
                     private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval = args[0].createEvaluator(outInput);
-                    private int offset;
                     private String errorMessage = "This can not be an instance of date";
                     private AMutableDate aDate = new AMutableDate(0);
                     @SuppressWarnings("unchecked")
@@ -58,8 +62,6 @@
                     private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ANULL);
 
-                    private GregorianCalendarSystem gCalInstance = GregorianCalendarSystem.getInstance();
-
                     @Override
                     public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
 
@@ -69,217 +71,15 @@
                             byte[] serString = outInput.getByteArray();
                             if (serString[0] == SER_STRING_TYPE_TAG) {
 
-                                int length = ((serString[1] & 0xff) << 8) + ((serString[2] & 0xff) << 0) + 3;
+                                charAccessor.reset(serString, 3, 0);
+                                long chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, true);
 
-                                offset = 3;
-
-                                int year = 0, month = 0, day = 0;
-                                int timezone = 0;
-                                boolean positive = true;
-                                if (serString[offset + 4] == '-' || serString[offset + 5] == '-') {
-                                    // parse extended form
-                                    if (serString[offset] == '-') {
-                                        offset++;
-                                        positive = false;
-                                    }
-
-                                    if (serString[offset + 4] != '-' || serString[offset + 7] != '-')
-                                        throw new AlgebricksException(errorMessage);
-
-                                    // year
-                                    for (int i = 0; i < 4; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            year = year * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.YEAR]
-                                            || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.YEAR]) {
-                                        throw new AlgebricksException(errorMessage + ": year " + year);
-                                    }
-
-                                    offset += 5;
-
-                                    // month
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            month = month * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MONTH]
-                                            || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MONTH]) {
-                                        throw new AlgebricksException(errorMessage + ": month " + month);
-                                    }
-
-                                    offset += 3;
-
-                                    // day
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            day = day * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.DAY]
-                                            || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.DAY]) {
-                                        throw new AlgebricksException(errorMessage + ": day " + day);
-                                    }
-
-                                    offset += 2;
-
-                                    if (!positive)
-                                        year *= -1;
-
-                                    if (length > offset) {
-                                        if (serString[offset] != 'Z') {
-                                            if ((serString[offset] != '+' && serString[offset] != '-')
-                                                    || (serString[offset + 3] != ':'))
-                                                throw new AlgebricksException(errorMessage);
-
-                                            short timezoneHour = 0;
-                                            short timezoneMinute = 0;
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 1 + i] >= '0' && serString[offset + 1 + i] <= '9'))
-                                                    timezoneHour = (short) (timezoneHour * 10
-                                                            + serString[offset + 1 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-
-                                            }
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 4 + i] >= '0' && serString[offset + 4 + i] <= '9'))
-                                                    timezoneMinute = (short) (timezoneMinute * 10
-                                                            + serString[offset + 4 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-
-                                                if (serString[offset] == '-')
-                                                    timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                                                else
-                                                    timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                                            }
-                                        }
-                                    }
-
-                                } else {
-                                    // parse basic form
-                                    if (serString[offset] == '-') {
-                                        offset++;
-                                        positive = false;
-                                    }
-
-                                    // year
-                                    for (int i = 0; i < 4; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            year = year * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.YEAR]
-                                            || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.YEAR]) {
-                                        throw new AlgebricksException(errorMessage + ": year " + year);
-                                    }
-
-                                    offset += 4;
-
-                                    // month
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            month = month * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MONTH]
-                                            || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MONTH]) {
-                                        throw new AlgebricksException(errorMessage + ": month " + month);
-                                    }
-
-                                    offset += 2;
-
-                                    // day
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            day = day * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.DAY]
-                                            || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.DAY]) {
-                                        throw new AlgebricksException(errorMessage + ": day " + day);
-                                    }
-
-                                    offset += 2;
-
-                                    if (!positive)
-                                        year *= -1;
-
-                                    if (length > offset) {
-                                        if (serString[offset] != 'Z') {
-                                            if ((serString[offset] != '+' && serString[offset] != '-'))
-                                                throw new AlgebricksException(errorMessage);
-
-                                            short timezoneHour = 0;
-                                            short timezoneMinute = 0;
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if (serString[offset + 1 + i] >= '0'
-                                                        && serString[offset + 1 + i] <= '9')
-                                                    timezoneHour = (short) (timezoneHour * 10
-                                                            + serString[offset + 1 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-
-                                            }
-
-                                            if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-                                                    || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-                                                throw new AlgebricksException(errorMessage + ": time zone hour "
-                                                        + timezoneHour);
-                                            }
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if (serString[offset + 3 + i] >= '0'
-                                                        && serString[offset + 3 + i] <= '9')
-                                                    timezoneMinute = (short) (timezoneMinute * 10
-                                                            + serString[offset + 3 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-                                            }
-
-                                            if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-                                                    || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-                                                throw new AlgebricksException(errorMessage + ": time zone minute "
-                                                        + timezoneMinute);
-                                            }
-
-                                            if (serString[offset] == '-')
-                                                timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                                            else
-                                                timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                                        }
-                                    }
-                                }
-
-                                long chrononTimeInMs = gCalInstance.getChronon(year, month, day, 0, 0, 0, 0, timezone);
-                                aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY));
+                                short temp = 0;
                                 if (chrononTimeInMs < 0
                                         && chrononTimeInMs % GregorianCalendarSystem.CHRONON_OF_DAY != 0)
-                                    aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY) - 1);
+                                    temp = 1;
+
+                                aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY) - temp);
 
                                 dateSerde.serialize(aDate, out);
                             } else if (serString[0] == SER_NULL_TYPE_TAG)
@@ -289,6 +89,8 @@
 
                         } catch (IOException e1) {
                             throw new AlgebricksException(errorMessage);
+                        } catch (Exception e2) {
+                            throw new AlgebricksException(e2.getMessage());
                         }
                     }
                 };
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 2c711a5..f077da9 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
@@ -8,7 +8,8 @@
 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.GregorianCalendarSystem;
+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;
@@ -30,6 +31,9 @@
             false);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+    private final static ByteArrayCharSequenceAccessor charAccessor = new ByteArrayCharSequenceAccessor();
+
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
             return new ADateTimeConstructorDescriptor();
@@ -49,7 +53,6 @@
 
                     private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval = args[0].createEvaluator(outInput);
-                    private int offset;
                     private String errorMessage = "This can not be an instance of datetime";
                     private AMutableDateTime aDateTime = new AMutableDateTime(0L);
                     @SuppressWarnings("unchecked")
@@ -59,8 +62,6 @@
                     private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ANULL);
 
-                    private GregorianCalendarSystem gCalInstance = GregorianCalendarSystem.getInstance();
-
                     @Override
                     public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
 
@@ -69,379 +70,26 @@
                             eval.evaluate(tuple);
                             byte[] serString = outInput.getByteArray();
                             if (serString[0] == SER_STRING_TYPE_TAG) {
-                                int length = ((serString[1] & 0xff) << 8) + ((serString[2] & 0xff) << 0) + 3;
-                                offset = 3;
+                                charAccessor.reset(serString, 3, 0);
 
-                                int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0, millis = 0;
-                                int timezone = 0;
+                                // +1 if it is negative (-)
+                                short timeOffset = (short) ((charAccessor.getCharAt(0) == '-') ? 1 : 0);
 
-                                boolean positive = true;
-                                boolean isExtendedForm = false;
-                                if (serString[offset + 13] == ':' || serString[offset + 14] == ':') {
-                                    isExtendedForm = true;
-                                }
-                                if (isExtendedForm) {
-                                    // parse extended form
-                                    if (serString[offset] == '-') {
-                                        offset++;
-                                        positive = false;
-                                    }
+                                if (charAccessor.getCharAt(timeOffset + 10) != 'T'
+                                        && charAccessor.getCharAt(timeOffset + 8) != 'T')
+                                    throw new AlgebricksException(errorMessage + ": missing T");
 
-                                    if (serString[offset + 4] != '-' || serString[offset + 7] != '-')
-                                        throw new AlgebricksException(errorMessage);
+                                // if extended form 11, else 9
+                                timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11)
+                                        : (short) (9);
 
-                                    // year
-                                    for (int i = 0; i < 4; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            year = year * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
+                                long chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, false);
 
-                                    if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.YEAR]
-                                            || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.YEAR]) {
-                                        throw new AlgebricksException(errorMessage + ": year " + year);
-                                    }
+                                charAccessor.reset(serString, 3, timeOffset);
 
-                                    offset += 5;
+                                chrononTimeInMs += ADateAndTimeParser.parseTimePart(charAccessor);
 
-                                    // month
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            month = month * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MONTH]
-                                            || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MONTH]) {
-                                        throw new AlgebricksException(errorMessage + ": month " + month);
-                                    }
-
-                                    offset += 3;
-
-                                    // day
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            day = day * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.DAY]
-                                            || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.DAY]) {
-                                        throw new AlgebricksException(errorMessage + ": day " + day);
-                                    }
-
-                                    offset += 2;
-
-                                    if (!positive)
-                                        year *= -1;
-
-                                    // skip the "T" separator
-                                    offset += 1;
-
-                                    if (serString[offset + 2] != ':' || serString[offset + 5] != ':')
-                                        throw new AlgebricksException(errorMessage);
-
-                                    // hour
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            hour = hour * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (hour < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.HOUR]
-                                            || hour > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.HOUR]) {
-                                        throw new AlgebricksException(errorMessage + ": hour " + hour);
-                                    }
-
-                                    offset += 3;
-
-                                    // minute
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            min = min * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (min < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MINUTE]
-                                            || min > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MINUTE]) {
-                                        throw new AlgebricksException(errorMessage + ": min " + min);
-                                    }
-
-                                    offset += 3;
-
-                                    // second
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            sec = sec * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (sec < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.SECOND]
-                                            || sec > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.SECOND]) {
-                                        throw new AlgebricksException(errorMessage + ": sec " + sec);
-                                    }
-
-                                    offset += 2;
-
-                                    if (length > offset && serString[offset] == '.') {
-
-                                        offset++;
-                                        int i = 0;
-                                        for (; i < 3 && offset + i < length; i++) {
-                                            if (serString[offset + i] >= '0' && serString[offset + i] <= '9') {
-                                                millis = millis * 10 + serString[offset + i] - '0';
-                                            } else {
-                                                break;
-                                            }
-                                        }
-
-                                        offset += i;
-
-                                        for (; i < 3; i++) {
-                                            millis = millis * 10;
-                                        }
-
-                                        for (; offset < length; offset++) {
-                                            if (serString[offset] < '0' || serString[offset] > '9') {
-                                                break;
-                                            }
-                                        }
-                                    }
-
-                                    if (length > offset) {
-                                        if (serString[offset] != 'Z') {
-                                            if ((serString[offset] != '+' && serString[offset] != '-')
-                                                    || (serString[offset + 3] != ':'))
-                                                throw new AlgebricksException(errorMessage);
-
-                                            short timezoneHour = 0;
-                                            short timezoneMinute = 0;
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 1 + i] >= '0' && serString[offset + 1 + i] <= '9'))
-                                                    timezoneHour = (short) (timezoneHour * 10
-                                                            + serString[offset + 1 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-
-                                            }
-
-                                            if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-                                                    || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-                                                throw new AlgebricksException(errorMessage + ": time zone hour "
-                                                        + timezoneHour);
-                                            }
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 4 + i] >= '0' && serString[offset + 4 + i] <= '9'))
-                                                    timezoneMinute = (short) (timezoneMinute * 10
-                                                            + serString[offset + 4 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-                                            }
-
-                                            if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-                                                    || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-                                                throw new AlgebricksException(errorMessage + ": time zone minute "
-                                                        + timezoneMinute);
-                                            }
-
-                                            if (serString[offset] == '-')
-                                                timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                                            else
-                                                timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                                        }
-                                    }
-
-                                } else {
-                                    // parse basic form
-                                    if (serString[offset] == '-') {
-                                        offset++;
-                                        positive = false;
-                                    }
-
-                                    // year
-                                    for (int i = 0; i < 4; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            year = year * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.YEAR]
-                                            || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.YEAR]) {
-                                        throw new AlgebricksException(errorMessage + ": year " + year);
-                                    }
-
-                                    offset += 4;
-
-                                    // month
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            month = month * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MONTH]
-                                            || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MONTH]) {
-                                        throw new AlgebricksException(errorMessage + ": month " + month);
-                                    }
-
-                                    offset += 2;
-
-                                    // day
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            day = day * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.DAY]
-                                            || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.DAY]) {
-                                        throw new AlgebricksException(errorMessage + ": day " + day);
-                                    }
-
-                                    offset += 2;
-
-                                    if (!positive)
-                                        year *= -1;
-
-                                    // hour
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            hour = hour * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (hour < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.HOUR]
-                                            || hour > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.HOUR]) {
-                                        throw new AlgebricksException(errorMessage + ": hour " + hour);
-                                    }
-
-                                    offset += 2;
-
-                                    // minute
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            min = min * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (min < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.MINUTE]
-                                            || min > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.MINUTE]) {
-                                        throw new AlgebricksException(errorMessage + ": min " + min);
-                                    }
-
-                                    offset += 2;
-
-                                    // second
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                            sec = sec * 10 + serString[offset + i] - '0';
-                                        } else {
-                                            throw new AlgebricksException(errorMessage);
-                                        }
-                                    }
-
-                                    if (sec < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.SECOND]
-                                            || sec > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.SECOND]) {
-                                        throw new AlgebricksException(errorMessage + ": sec " + sec);
-                                    }
-
-                                    offset += 2;
-
-                                    if (length > offset) {
-                                        int i = 0;
-                                        for (; i < 3 && offset + i < length; i++) {
-                                            if (serString[offset + i] >= '0' && serString[offset + i] <= '9') {
-                                                millis = millis * 10 + serString[offset + i] - '0';
-                                            } else {
-                                                break;
-                                            }
-                                        }
-
-                                        offset += i;
-
-                                        for (; i < 3; i++) {
-                                            millis = millis * 10;
-                                        }
-
-                                        for (; offset < length; offset++) {
-                                            if (serString[offset] < '0' || serString[offset] > '9') {
-                                                break;
-                                            }
-                                        }
-                                    }
-
-                                    if (length > offset) {
-                                        if (serString[offset] != 'Z') {
-                                            if ((serString[offset] != '+' && serString[offset] != '-'))
-                                                throw new AlgebricksException(errorMessage);
-
-                                            short timezoneHour = 0;
-                                            short timezoneMinute = 0;
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 1 + i] >= '0' && serString[offset + 1 + i] <= '9'))
-                                                    timezoneHour = (short) (timezoneHour * 10
-                                                            + serString[offset + 1 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-
-                                            }
-
-                                            if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-                                                    || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-                                                throw new AlgebricksException(errorMessage + ": time zone hour "
-                                                        + timezoneHour);
-                                            }
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 3 + i] >= '0' && serString[offset + 3 + i] <= '9'))
-                                                    timezoneMinute = (short) (timezoneMinute * 10
-                                                            + serString[offset + 3 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-                                            }
-
-                                            if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-                                                    || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-                                                throw new AlgebricksException(errorMessage + ": time zone minute "
-                                                        + timezoneMinute);
-                                            }
-
-                                            if (serString[offset] == '-')
-                                                timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                                            else
-                                                timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                                        }
-                                    }
-                                }
-
-                                aDateTime.setValue(gCalInstance.getChronon(year, month, day, hour, min, sec,
-                                        (int) millis, timezone));
-
+                                aDateTime.setValue(chrononTimeInMs);
                                 datetimeSerde.serialize(aDateTime, out);
                             } else if (serString[0] == SER_NULL_TYPE_TAG)
                                 nullSerde.serialize(ANull.NULL, out);
@@ -449,6 +97,8 @@
                                 throw new AlgebricksException(errorMessage);
                         } catch (IOException e1) {
                             throw new AlgebricksException(errorMessage);
+                        } catch (Exception e) {
+                            throw new AlgebricksException(e.getMessage());
                         }
                     }
                 };
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 58a26ba..0486c04 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
@@ -1,13 +1,14 @@
 package edu.uci.ics.asterix.runtime.evaluators.constructors;
 
 import java.io.DataOutput;
-import java.io.IOException;
 
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
 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.ANull;
+import edu.uci.ics.asterix.om.base.temporal.ADurationParser;
+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;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -29,6 +30,9 @@
             false);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+    private final static ByteArrayCharSequenceAccessor charAccessor = new ByteArrayCharSequenceAccessor();
+
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
             return new ADurationConstructorDescriptor();
@@ -48,11 +52,6 @@
 
                     private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval = args[0].createEvaluator(outInput);
-                    private int offset;
-                    private int value = 0, hour = 0, minute = 0, second = 0, millisecond = 0, year = 0, month = 0,
-                            day = 0;
-                    private boolean isYear = true, isMonth = true, isDay = true, isHour = true, isMinute = true,
-                            isSecond = true, isMillisecond = true, isTime = false, timeItem = true, positive = true;
                     private String errorMessage = "This can not be an instance of duration";
                     private AMutableDuration aDuration = new AMutableDuration(0, 0);
                     @SuppressWarnings("unchecked")
@@ -69,118 +68,21 @@
                             outInput.reset();
                             eval.evaluate(tuple);
                             byte[] serString = outInput.getByteArray();
+
                             if (serString[0] == SER_STRING_TYPE_TAG) {
-                                offset = 3;
-                                if (serString[offset] == '-') {
-                                    offset++;
-                                    positive = false;
-                                }
-                                if (serString[offset++] != 'P')
-                                    throw new AlgebricksException(errorMessage);
 
-                                for (; offset < outInput.getLength(); offset++) {
-                                    if (serString[offset] >= '0' && serString[offset] <= '9')
-                                        value = value * 10 + serString[offset] - '0';
-                                    else {
-                                        switch (serString[offset]) {
-                                            case 'Y':
-                                                if (isYear) {
-                                                    year = value;
-                                                    isYear = false;
-                                                } else
-                                                    throw new AlgebricksException(errorMessage);
-                                                break;
-                                            case 'M':
-                                                if (!isTime) {
-                                                    if (isMonth) {
-                                                        month = value;
-                                                        isMonth = false;
-                                                    } else
-                                                        throw new AlgebricksException(errorMessage);
-                                                } else if (isMinute) {
-                                                    minute = value;
-                                                    isMinute = false;
-                                                    timeItem = false;
-                                                } else
-                                                    throw new AlgebricksException(errorMessage);
-                                                break;
-                                            case 'D':
-                                                if (isDay) {
-                                                    day = value;
-                                                    isDay = false;
-                                                } else
-                                                    throw new AlgebricksException(errorMessage);
-                                                break;
-                                            case 'T':
-                                                if (!isTime) {
-                                                    isTime = true;
-                                                    timeItem = true;
-                                                } else
-                                                    throw new AlgebricksException(errorMessage);
-                                                break;
+                                charAccessor.reset(serString, 3, 0);
 
-                                            case 'H':
-                                                if (isHour) {
-                                                    hour = value;
-                                                    isHour = false;
-                                                    timeItem = false;
-                                                } else
-                                                    throw new AlgebricksException(errorMessage);
-                                                break;
-                                            case '.':
-                                                if (isMillisecond) {
-                                                    int i = 1;
-                                                    for (; offset + i < outInput.getLength(); i++) {
-                                                        if (serString[offset + i] >= '0'
-                                                                && serString[offset + i] <= '9') {
-                                                            if (i < 4)
-                                                                millisecond = millisecond * 10 + serString[offset + i]
-                                                                        - '0';
-                                                        } else
-                                                            break;
-                                                    }
-                                                    offset += i;
-                                                    isMillisecond = false;
-                                                    timeItem = false;
-                                                } else
-                                                    throw new AlgebricksException(errorMessage);
-                                            case 'S':
-                                                if (isSecond) {
-                                                    second = value;
-                                                    isSecond = false;
-                                                    timeItem = false;
-                                                } else
-                                                    throw new AlgebricksException(errorMessage);
-                                                break;
-                                            default:
-                                                throw new AlgebricksException(errorMessage);
+                                ADurationParser.parse(charAccessor, aDuration);
 
-                                        }
-                                        value = 0;
-                                    }
-                                }
-
-                                if (isTime && timeItem)
-                                    throw new AlgebricksException(errorMessage);
-
-                                //                                if (isYear && isMonth && isDay && !isTime)
-                                //                                    throw new AlgebricksException(errorMessage);
-
-                                if (positive)
-                                    aDuration.setValue(year * 12 + month, day * 24 * 3600 * 1000L + 3600 * 1000L * hour
-                                            + 60 * minute * 1000L + second * 1000L + millisecond);
-                                else
-                                    aDuration.setValue(-1 * (year * 12 + month), -1
-                                            * (day * 24 * 3600 * 1000L + 3600 * 1000L * hour + 60 * minute * 1000L
-                                                    + second * 1000L + millisecond));
                                 durationSerde.serialize(aDuration, out);
                             } else if (serString[0] == SER_NULL_TYPE_TAG)
                                 nullSerde.serialize(ANull.NULL, out);
                             else
                                 throw new AlgebricksException(errorMessage);
 
-                        } catch (IOException e1) {
-                            throw new AlgebricksException(errorMessage);
+                        } catch (Exception e) {
+                            throw new AlgebricksException(e.getMessage());
                         }
                     }
                 };
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 a173ba7..c99fc30 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
@@ -8,7 +8,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.GregorianCalendarSystem;
+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;
@@ -29,6 +30,7 @@
     public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "time", 1, false);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static ByteArrayCharSequenceAccessor charAccessor = new ByteArrayCharSequenceAccessor();
 
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
@@ -49,7 +51,6 @@
 
                     private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval = args[0].createEvaluator(outInput);
-                    private int offset;
                     private String errorMessage = "This can not be an instance of time";
                     private AMutableTime aTime = new AMutableTime(0);
                     @SuppressWarnings("unchecked")
@@ -67,242 +68,10 @@
                             eval.evaluate(tuple);
                             byte[] serString = outInput.getByteArray();
                             if (serString[0] == SER_STRING_TYPE_TAG) {
+                                charAccessor.reset(serString, 3, 0);
+                                int chrononTimeInMs = ADateAndTimeParser.parseTimePart(charAccessor);
 
-                                offset = 3;
-
-                                int length = ((serString[1] & 0xff) << 8) + ((serString[2] & 0xff) << 0) + 3;
-
-                                int hour = 0, min = 0, sec = 0, millis = 0;
-                                int timezone = 0;
-                                boolean isExtendedForm = false;
-                                if (serString[offset + 2] == ':') {
-                                    isExtendedForm = true;
-                                }
-                                if (isExtendedForm) {
-                                    // parse extended form
-                                    if (serString[offset] == '-' || serString[offset + 5] != ':')
-                                        throw new AlgebricksException(errorMessage);
-
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9'))
-                                            hour = hour * 10 + serString[offset + i] - '0';
-                                        else
-                                            throw new AlgebricksException(errorMessage);
-
-                                    }
-
-                                    if (hour < 0 || hour > 23) {
-                                        throw new AlgebricksException(errorMessage + ": hour " + hour);
-                                    }
-
-                                    offset += 3;
-
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9'))
-                                            min = min * 10 + serString[offset + i] - '0';
-                                        else
-                                            throw new AlgebricksException(errorMessage);
-
-                                    }
-
-                                    if (min < 0 || min > 59) {
-                                        throw new AlgebricksException(errorMessage + ": min " + min);
-                                    }
-
-                                    offset += 3;
-
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9'))
-                                            sec = sec * 10 + serString[offset + i] - '0';
-                                        else
-                                            throw new AlgebricksException(errorMessage);
-
-                                    }
-
-                                    if (sec < 0 || sec > 59) {
-                                        throw new AlgebricksException(errorMessage + ": sec " + sec);
-                                    }
-
-                                    offset += 2;
-
-                                    if (length > offset && serString[offset] == '.') {
-
-                                        offset++;
-                                        int i = 0;
-                                        for (; i < 3 && offset + i < length; i++) {
-                                            if (serString[offset + i] >= '0' && serString[offset + i] <= '9') {
-                                                millis = millis * 10 + serString[offset + i] - '0';
-                                            } else {
-                                                break;
-                                            }
-                                        }
-
-                                        offset += i;
-
-                                        for (; i < 3; i++) {
-                                            millis = millis * 10;
-                                        }
-
-                                        for (; offset < length; offset++) {
-                                            if (serString[offset] < '0' || serString[offset] > '9') {
-                                                break;
-                                            }
-                                        }
-                                    }
-
-                                    if (length > offset) {
-                                        if (serString[offset] != 'Z') {
-                                            if ((serString[offset] != '+' && serString[offset] != '-')
-                                                    || (serString[offset + 3] != ':'))
-                                                throw new AlgebricksException(errorMessage);
-
-                                            short timezoneHour = 0;
-                                            short timezoneMinute = 0;
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 1 + i] >= '0' && serString[offset + 1 + i] <= '9'))
-                                                    timezoneHour = (short) (timezoneHour * 10
-                                                            + serString[offset + 1 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-
-                                            }
-
-                                            if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
-                                                    || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
-                                                throw new AlgebricksException(errorMessage + ": time zone hour "
-                                                        + timezoneHour);
-                                            }
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 4 + i] >= '0' && serString[offset + 4 + i] <= '9'))
-                                                    timezoneMinute = (short) (timezoneMinute * 10
-                                                            + serString[offset + 4 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-                                            }
-
-                                            if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
-                                                    || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
-                                                throw new AlgebricksException(errorMessage + ": time zone minute "
-                                                        + timezoneMinute);
-                                            }
-
-                                            if (serString[offset] == '-')
-                                                timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                                            else
-                                                timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                                        }
-                                    }
-
-                                } else {
-                                    // parse basic form
-
-                                    if (serString[offset] == '-')
-                                        throw new AlgebricksException(errorMessage);
-
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9'))
-                                            hour = hour * 10 + serString[offset + i] - '0';
-                                        else
-                                            throw new AlgebricksException(errorMessage);
-
-                                    }
-
-                                    if (hour < 0 || hour > 23) {
-                                        throw new AlgebricksException(errorMessage + ": hour " + hour);
-                                    }
-
-                                    offset += 2;
-
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9'))
-                                            min = min * 10 + serString[offset + i] - '0';
-                                        else
-                                            throw new AlgebricksException(errorMessage);
-
-                                    }
-
-                                    if (min < 0 || min > 59) {
-                                        throw new AlgebricksException(errorMessage + ": min " + min);
-                                    }
-
-                                    offset += 2;
-
-                                    for (int i = 0; i < 2; i++) {
-                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9'))
-                                            sec = sec * 10 + serString[offset + i] - '0';
-                                        else
-                                            throw new AlgebricksException(errorMessage);
-
-                                    }
-
-                                    if (sec < 0 || sec > 59) {
-                                        throw new AlgebricksException(errorMessage + ": sec " + sec);
-                                    }
-
-                                    offset += 2;
-
-                                    if (length > offset) {
-                                        int i = 0;
-                                        for (; i < 3 && offset + i < length; i++) {
-                                            if ((serString[offset + i] >= '0' && serString[offset + i] <= '9')) {
-                                                millis = millis * 10 + serString[offset + i] - '0';
-                                            } else {
-                                                break;
-                                            }
-                                        }
-
-                                        offset += i;
-
-                                        for (; i < 3; i++) {
-                                            millis = millis * 10;
-                                        }
-
-                                        for (; offset < length; offset++) {
-                                            if (serString[offset] < '0' || serString[offset] > '9') {
-                                                break;
-                                            }
-                                        }
-                                    }
-
-                                    if (length > offset) {
-                                        if (serString[offset] != 'Z') {
-                                            if ((serString[offset] != '+' && serString[offset] != '-'))
-                                                throw new AlgebricksException(errorMessage);
-
-                                            short timezoneHour = 0;
-                                            short timezoneMinute = 0;
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 1 + i] >= '0' && serString[offset + 1 + i] <= '9'))
-                                                    timezoneHour = (short) (timezoneHour * 10
-                                                            + serString[offset + 1 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-
-                                            }
-
-                                            for (int i = 0; i < 2; i++) {
-                                                if ((serString[offset + 3 + i] >= '0' && serString[offset + 3 + i] <= '9'))
-                                                    timezoneMinute = (short) (timezoneMinute * 10
-                                                            + serString[offset + 3 + i] - '0');
-                                                else
-                                                    throw new AlgebricksException(errorMessage);
-
-                                            }
-
-                                            if (serString[offset] == '-')
-                                                timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                                            else
-                                                timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
-                                        }
-                                    }
-                                }
-
-                                aTime.setValue(GregorianCalendarSystem.getInstance().getChronon(hour, min, sec, millis,
-                                        timezone));
-
+                                aTime.setValue(chrononTimeInMs);
                                 timeSerde.serialize(aTime, out);
 
                             } else if (serString[0] == SER_NULL_TYPE_TAG)
@@ -311,6 +80,8 @@
                                 throw new AlgebricksException(errorMessage);
                         } catch (IOException e1) {
                             throw new AlgebricksException(errorMessage);
+                        } catch (Exception e) {
+                            throw new AlgebricksException(e.getMessage());
                         }
                     }
                 };