merged asterix_stabilization r348:407

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_temporal_fixes@408 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-app/data/events/tiny/event.adm b/asterix-app/data/events/tiny/event.adm
index 21fd7e7..5e9d4b3 100644
--- a/asterix-app/data/events/tiny/event.adm
+++ b/asterix-app/data/events/tiny/event.adm
@@ -5,8 +5,8 @@
     "sponsoring_sigs": [ { "sig_id": 14, "chapter_name": "San Clemente" }, 
                          { "sig_id": 14, "chapter_name": "Laguna Beach" } ],
     "interest_keywords": {{ "art", "landscape", "nature", "vernissage" }},
-    "start_time": datetime( "2011-02-23T18:00:00:000-08:00" ),
-    "end_time": datetime( "2011-02-23T21:00:00:000-08:00" ) 
+    "start_time": datetime( "2011-02-23T18:00:00.000-08:00" ),
+    "end_time": datetime( "2011-02-23T21:00:00.000-08:00" ) 
   }
   { 
     "event_id": 941, 
@@ -16,8 +16,8 @@
     "sponsoring_sigs": [ { "sig_id": 31, "chapter_name": "Huntington Beach" } ],
     "interest_keywords": {{ "scuba", "diving", "aquatics" }},
     "price": 40.00,
-    "start_time": datetime( "2010-10-16T09:00:00:000-08:00" ),
-    "end_time": datetime( "2010-10-16T12:00:00:000-08:00" )
+    "start_time": datetime( "2010-10-16T09:00:00.000-08:00" ),
+    "end_time": datetime( "2010-10-16T12:00:00.000-08:00" )
   }
   { 
     "event_id": 1042, 
@@ -26,7 +26,7 @@
     "sponsoring_sigs": [ { "sig_id": 14, "chapter_name": "Laguna Beach" } ],
     "interest_keywords": {{ "architecture", "photography" }},
     "price": 10.00,
-    "start_time": datetime( "2011-02-23T17:00:00:000-08:00" ),
-    "end_time": datetime( "2011-02-23T19:00:00:000-08:00" ) 
+    "start_time": datetime( "2011-02-23T17:00:00.000-08:00" ),
+    "end_time": datetime( "2011-02-23T19:00:00.000-08:00" ) 
   } 
   
\ No newline at end of file
diff --git a/asterix-app/data/nontagged/allData.json b/asterix-app/data/nontagged/allData.json
index e70257a..5f7bf3b 100644
--- a/asterix-app/data/nontagged/allData.json
+++ b/asterix-app/data/nontagged/allData.json
@@ -1,2 +1,2 @@
-{ "id": 10, "name": string("Nancy"), "age": 32.5f, "salary": 12.000 ,"married": boolean("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:30Z"), "datetime": datetime("-1951-12-27T12:20:30"),  "duration": duration("D10Y11M12DT10H50M30S"),  "location2d": point("41.00,44.00"),  "location3d": point3d("44.00,13.00,41.00"), "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": string("Nancy"), "age": 32.5f, "salary": 12.000 ,"married": boolean("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:30Z"), "datetime": datetime("-1951-12-27T12:20:30"),  "duration": duration("P10Y11M12DT10H50M30S"),  "location2d": point("41.00,44.00"),  "location3d": point3d("44.00,13.00,41.00"), "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/data/nontagged/tempData.json b/asterix-app/data/nontagged/tempData.json
index 1fef3ab..a439ab0 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("D30Y10M15DT10H30M50S"), "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("D10M15DT10H50S"), "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("-DT50S"), "date4": date("-2011-01-27Z"), "time4": time("12:20:30Z"), "datetime4": datetime("-1951-12-27T12:20:30:250Z"), "duration4": duration("-D10M"), "date5": date("2011-01-27"), "time5": time("12:20:30"), "datetime5": datetime("1951-12-27T12:20:30"),  "duration5": duration("D30Y10M15DT10H30M50S") }
+{ "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") }
 
diff --git a/asterix-app/data/nontagged/tempData.txt b/asterix-app/data/nontagged/tempData.txt
index 6615812..8790101 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("D30Y10M15DT10H30M50S")
-20|date("2011-01-27-05:00")|time("12:20:30:999-05:00")|datetime("1951-12-27T12:20:30:250-08:45")|duration("D10M15DT10H50S")
-30|date("-2011-01-27-05:00")|time("12:20:30:999Z")|datetime("-1951-12-27T12:20:30:250-08:15")|duration("-DT50S")
-40|date("-2011-01-27Z")|time("12:20:30Z")|datetime("-1951-12-27T12:20:30:250Z")|duration("-D10M")
+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")
diff --git a/asterix-app/src/test/resources/aqljts/results/nested_01.adm b/asterix-app/src/test/resources/aqljts/results/nested_01.adm
index 54444c7..27de5c0 100644
--- a/asterix-app/src/test/resources/aqljts/results/nested_01.adm
+++ b/asterix-app/src/test/resources/aqljts/results/nested_01.adm
@@ -30,4 +30,4 @@
 ARecordType: 
 field: t
 AbstractCollectionType: 
-ADateTime: { 2011-9-16:11:0:0:0:0:0 }
+ADateTime: { 2011-09-16T11:00:00.000Z }
diff --git a/asterix-app/src/test/resources/runtimets/queries/comparison/datetime_order.aql b/asterix-app/src/test/resources/runtimets/queries/comparison/datetime_order.aql
index 2e151ab..f2d8208 100644
--- a/asterix-app/src/test/resources/runtimets/queries/comparison/datetime_order.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/comparison/datetime_order.aql
@@ -11,7 +11,13 @@
 let $dt3 := datetime("2005-01-01T00:00:00+04:00")
 let $dt4 := datetime("2011-12-31T13:00:00-11:00")
 let $dt5 := datetime("2012-04-06T00:00:00Z")
+let $dt6 := datetime("-1937-07-07T23:00:00+08:00")
+let $dt7 := datetime("-1600-03-01T00:00:00.384+06:00")
+let $dt8 := datetime("-1600-02-29T23:59:59.999Z")
+let $dt9 := datetime("2000-02-29T23:59:59.999Z")
+let $dt10 := datetime("2000-03-01T01:59:59.999+07:00")
+let $dt11 := datetime("-1600-03-01T00:00:00.384-06:00")
 
-for $dt in [$dt1, $dt2, $dt3, $dt4, $dt5]
+for $dt in [$dt1, $dt2, $dt3, $dt4, $dt5, $dt6, $dt7, $dt8, $dt9, $dt10, $dt11]
 order by $dt
 return $dt
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/comparison/datetime_tzeq.aql b/asterix-app/src/test/resources/runtimets/queries/comparison/datetime_tzeq.aql
index e38bdae..1a0bb52 100644
--- a/asterix-app/src/test/resources/runtimets/queries/comparison/datetime_tzeq.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/comparison/datetime_tzeq.aql
@@ -8,6 +8,10 @@
 
 let $dt1 := datetime("2011-12-31T14:00:00-10:00")
 let $dt2 := datetime("2012-01-01T00:00:00Z")
+let $dt3 := datetime("2000-03-01T02:00:00+04:00")
+let $dt4 := datetime("2000-02-29T22:00:00Z")
+let $r1 := $dt1 = $dt2
+let $r2 := $dt3 = $dt4
 
 
-return [$dt1 = $dt2]
\ No newline at end of file
+return { "result1": $r1,"result2": $r2 }
\ No newline at end of file
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 c889627..9cc3d15 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
@@ -11,5 +11,11 @@
 let $c5 := date("-1987-11-19+08:30")
 let $c6 := date("0001-12-27")
 let $c7 := date("-1951-01-27-01:45")
-return {"date1": $c1, "date2": $c2, "date3": $c3, "date4": $c4, "date5": $c5, "date6": $c6, "date7": $c7}
+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}
 
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 611feff..b883b8a 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
@@ -1,13 +1,22 @@
+drop dataverse test if exists;
+create dataverse test;
 use dataverse test;
 
 write output to nc1:"rttest/constructor_datetime_01.adm";
 
-let $c1 := datetime("2010-10-30T10:50:56:999+05:45")
-let $c2 := datetime("2010-10-30T10:30:56:250-10:00")
-let $c3 := datetime("1987-11-19T09:20:00:200")
+let $c1 := datetime("2010-10-30T10:50:56.999+05:45")
+let $c2 := datetime("2010-10-30T10:30:56.250-10:00")
+let $c3 := datetime("1987-11-19T09:20:00.200Z")
 let $c4 := datetime("1987-11-19T10:50:56Z")
-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:15")
-return {"datetime1": $c1, "datetime2": $c2, "datetime3": $c3, "datetime4": $c4, "datetime5": $c5, "datetime6": $c6, "datetime7": $c7}
+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")
+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 011996c..4d9df8c 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
@@ -4,13 +4,18 @@
 
 write output to nc1:"rttest/constructor_duration_01.adm";
 
-let $c1 := duration("D30Y10M25DT13H12M50S")
-let $c2 := duration("D25DT13H12M50S")
-let $c3 := duration("DT13H12M50S")
-let $c4 := duration("D30YT12MS")
-let $c5 := duration("DT13H")
-let $c6 := duration("-D30Y10M25DT13H12M50S")
-let $c7 := duration("-D25DT13H12M50S")
-let $c8 := duration("-DT13H50S")
-return {"duration1": $c1, "duration2": $c2, "duration3": $c3, "duration4": $c4, "duration5": $c5, "duration6": $c6, "duration7": $c7, "duration8": $c8}
+let $c1 := duration("P30Y10M25DT13H12M50S")
+let $c2 := duration("P25DT13H12M50S")
+let $c3 := duration("PT13H12M50S")
+let $c4 := duration("P30YT12MS")
+let $c5 := duration("PT13H")
+let $c6 := duration("-P30Y10M25DT13H12M50S")
+let $c7 := duration("-P25DT13H12M50S")
+let $c8 := duration("-PT13H50S")
+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}
 
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 caa90f0..bb5d313 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
@@ -4,12 +4,16 @@
 
 write output to nc1:"rttest/constructor_time_01.adm";
 
-let $c1 := time("10:50:56:200+05:00")
-let $c2 := time("10:50:56:200-10:15")
+let $c1 := time("10:50:56.200+05:00")
+let $c2 := time("10:50:56.200-10:15")
 let $c3 := time("10:50:56")
-let $c4 := time("10:50:56:200Z")
-let $c5 := time("23:59:59:999-13:30")
-let $c6 := time("24:00:00:000+14:45")
-let $c7 := time("12:59:00:019-01:00")
-return {"time1": $c1, "time2": $c2, "time3": $c3, "time4": $c4, "time5": $c5, "time6": $c6, "time7": $c7}
+let $c4 := time("10:50:56.200Z")
+let $c5 := time("23:59:59.999-13:30")
+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 $c10 := time("12590001-0100")
+let $c11 := time("125900019382382398238-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/comparison/datetime_order.adm b/asterix-app/src/test/resources/runtimets/results/comparison/datetime_order.adm
index 14f3ab1..21f8208 100644
--- a/asterix-app/src/test/resources/runtimets/results/comparison/datetime_order.adm
+++ b/asterix-app/src/test/resources/runtimets/results/comparison/datetime_order.adm
@@ -1,5 +1,11 @@
-datetime("2005-01-01T00:00:00:000+04:00")
-datetime("2012-01-01T00:00:00:000+00:00")
-datetime("2011-12-31T14:00:00:000-10:00")
-datetime("2011-12-31T13:00:00:000-11:00")
-datetime("2012-04-06T00:00:00:000+00:00")
+datetime("-1937-07-07T15:00:00.000Z")
+datetime("-1600-02-29T18:00:00.384Z")
+datetime("-1600-02-29T23:59:59.999Z")
+datetime("-1600-03-01T06:00:00.384Z")
+datetime("2000-02-29T18:59:59.999Z")
+datetime("2000-02-29T23:59:59.999Z")
+datetime("2004-12-31T20:00:00.000Z")
+datetime("2012-01-01T00:00:00.000Z")
+datetime("2012-01-01T00:00:00.000Z")
+datetime("2012-01-01T00:00:00.000Z")
+datetime("2012-04-06T00:00:00.000Z")
diff --git a/asterix-app/src/test/resources/runtimets/results/comparison/datetime_tzeq.adm b/asterix-app/src/test/resources/runtimets/results/comparison/datetime_tzeq.adm
index 5dc225e..167bafb 100644
--- a/asterix-app/src/test/resources/runtimets/results/comparison/datetime_tzeq.adm
+++ b/asterix-app/src/test/resources/runtimets/results/comparison/datetime_tzeq.adm
@@ -1 +1 @@
-[ true ]
+{ "result1": true, "result2": true }
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 b0cb1e4..12f5755 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-30+05:00"), "date2": date("2010-10-30-10:15"), "date3": date("1987-11-19+00:00"), "date4": date("1987-11-19+00:00"), "date5": date("-1987-11-19+08:30"), "date6": date("0001-12-27+00:00"), "date7": date("-1951-01-27-01:45") }
\ No newline at end of file
+{ "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
diff --git a/asterix-app/src/test/resources/runtimets/results/constructor/datetime_01.adm b/asterix-app/src/test/resources/runtimets/results/constructor/datetime_01.adm
index 30d2cdb..54e76c4 100644
--- a/asterix-app/src/test/resources/runtimets/results/constructor/datetime_01.adm
+++ b/asterix-app/src/test/resources/runtimets/results/constructor/datetime_01.adm
@@ -1 +1 @@
-{ "datetime1": datetime("2010-10-30T10:50:56:980+05:45"), "datetime2": datetime("2010-10-30T10:30:56:240-10:00"), "datetime3": datetime("1987-11-19T09:20:00:200+00:00"), "datetime4": datetime("1987-11-19T10:50:56:000+00:00"), "datetime5": datetime("-1987-11-19T10:50:56:080-05:30"), "datetime6": datetime("-0001-11-19T10:50:56:700+00:00"), "datetime7": datetime("1951-12-27T12:20:15:000+00:00") }
+{ "datetime1": datetime("2010-10-30T05:05:56.999Z"), "datetime2": datetime("2010-10-30T20:30:56.250Z"), "datetime3": datetime("1987-11-19T09:20:00.200Z"), "datetime4": datetime("1987-11-19T10:50:56.000Z"), "datetime5": datetime("-1987-11-19T16:20:56.099Z"), "datetime6": datetime("-0001-11-19T10:50:56.719Z"), "datetime7": datetime("1951-12-27T12:20:15.000Z"), "datetime8": datetime("2043-11-19T10:50:56.719Z"), "datetime9": datetime("-1928-03-30T00:19:37.374Z"), "datetime10": datetime("-1928-03-29T11:19:37.374Z"), "datetime11": datetime("-1928-03-29T17:49:37.374Z"), "datetime12": datetime("-1928-03-29T11:19:37.374Z"), "datetime13": datetime("-1928-03-29T11:19:37.370Z"), "datetime14": datetime("-1928-02-29T23:19:37.370Z") }
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 b80ed1a..d9c8359 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("D30Y10M25DT13H12M50S"), "duration2": duration("D0Y0M25DT13H12M50S"), "duration3": duration("D0Y0M0DT13H12M50S"), "duration4": duration("D30Y0M0DT0H12M0S"), "duration5": duration("D0Y0M0DT13H0M0S"), "duration6": duration("-D30Y10M25DT13H12M50S"), "duration7": duration("-D0Y0M25DT13H12M50S"), "duration8": duration("-D0Y0M0DT13H0M50S") }
+{ "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") }
diff --git a/asterix-app/src/test/resources/runtimets/results/constructor/time_01.adm b/asterix-app/src/test/resources/runtimets/results/constructor/time_01.adm
index 2c932b5..ef6adc9 100644
--- a/asterix-app/src/test/resources/runtimets/results/constructor/time_01.adm
+++ b/asterix-app/src/test/resources/runtimets/results/constructor/time_01.adm
@@ -1 +1 @@
-{ "time1": time("10:50:56:200+05:00"), "time2": time("10:50:56:200-10:15"), "time3": time("10:50:56:000+00:00"), "time4": time("10:50:56:200+00:00"), "time5": time("23:59:59:980-13:30"), "time6": time("24:00:00:000+14:45"), "time7": time("12:59:00:000-01:00") }
+{ "time1": time("05:50:56.200Z"), "time2": time("21:05:56.200Z"), "time3": time("10:50:56.000Z"), "time4": time("10:50:56.200Z"), "time5": time("13:29:59.999Z"), "time6": time("09:15:00.000Z"), "time7": time("13:59:00.019Z"), "time8": time("13:59:00.010Z"), "time9": time("13:59:00.019Z"), "time10": time("13:59:00.010Z"), "time11": time("13:59:00.019Z") }
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 3fad2e3..06adc49 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-27+00:00"), "time": time("12:20:30:000+00:00"), "datetime": datetime("-1951-12-27T12:20:30:000+00:00"), "duration": duration("D10Y11M12DT10H50M30S"), "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-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") }
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 013a0cb..7d57c24 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-27+00:00"), "time": time("12:20:30:000+00:00"), "datetime": datetime("1951-12-27T12:20:30:000+00:00"), "duration": duration("D30Y10M15DT10H30M50S"), "date2": date("2011-01-27-05:00"), "time2": time("12:20:30:980-05:00"), "datetime2": datetime("1951-12-27T12:20:30:240-08:45"), "duration2": duration("D0Y10M15DT10H0M50S"), "date3": date("-2011-01-27-05:00"), "time3": time("12:20:30:980+00:00"), "datetime3": datetime("-1951-12-27T12:20:30:240-08:15"), "duration3": duration("-D0Y0M0DT0H0M50S"), "date4": date("-2011-01-27+00:00"), "time4": time("12:20:30:000+00:00"), "datetime4": datetime("-1951-12-27T12:20:30:240+00:00"), "duration4": duration("-D0Y10M0DT0H0M0S"), "date5": date("2011-01-27+00:00"), "time5": time("12:20:30:000+00:00"), "datetime5": datetime("1951-12-27T12:20:30:000+00:00"), "duration5": duration("D30Y10M15DT10H30M50S") }
\ No newline at end of file
+{ "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
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 f87b1e5..5f39ed9 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:000+00:00"), "datetime": datetime("1951-12-27T12:20:30:000+00:00"), "duration": duration("D30Y10M15DT10H30M50S") }
-{ "id": 20, "date": date("2011-01-27-05:00"), "time": time("12:20:30:980-05:00"), "datetime": datetime("1951-12-27T12:20:30:240-08:45"), "duration": duration("D0Y10M15DT10H0M50S") }
-{ "id": 30, "date": date("-2011-01-27-05:00"), "time": time("12:20:30:980+00:00"), "datetime": datetime("-1951-12-27T12:20:30:240-08:15"), "duration": duration("-D0Y0M0DT0H0M50S") }
-{ "id": 40, "date": date("-2011-01-27+00:00"), "time": time("12:20:30:000+00:00"), "datetime": datetime("-1951-12-27T12:20:30:240+00:00"), "duration": duration("-D0Y10M0DT0H0M0S") }
+{ "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") }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateTimeAscBinaryComparatorFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateTimeAscBinaryComparatorFactory.java
index b62c21a..2dd8785 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateTimeAscBinaryComparatorFactory.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateTimeAscBinaryComparatorFactory.java
@@ -1,6 +1,5 @@
 package edu.uci.ics.asterix.dataflow.data.nontagged.comparators;
 
-import edu.uci.ics.asterix.om.base.AMutableDateTime;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
 
@@ -15,41 +14,27 @@
     @Override
     public IBinaryComparator createBinaryComparator() {
         return new IBinaryComparator() {
-        	
-            private AMutableDateTime dt1 = new AMutableDateTime(0, 0, 0, 0, 0, 0, 0, 0, 0);
-            private AMutableDateTime dt2 = new AMutableDateTime(0, 0, 0, 0, 0, 0, 0, 0, 0);
 
             @Override
             public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
-                short year = (short) (((b1[s1] & 0xff) << 8) | b1[s1 + 1] & 0xff);
-                int time = ((b1[s1 + 4] & 0xff) << 24) | ((b1[s1 + 5] & 0xff) << 16) | ((b1[s1 + 6] & 0xff) << 8)
-                        | (b1[s1 + 7] & 0xff);
 
-                dt1.setValue(year >> 1, // year
-                        (year & 0x0001) * 8 + ((b1[s1 + 2] >>> 5) & 0x07), // month
-                        b1[s1 + 2] & 0x1f, // day
-                        (short) ((time) * 20 % 216000000 / 3600000), // hour
-                        (short) ((time) * 20 % 3600000 / 60000), // minutes
-                        (short) ((time) * 20 % 60000 / 1000), // seconds
-                        (short) ((time) * 20 % 1000), // milliseconds
-                        0, // microseconds
-                        b1[s1 + 3]); // timezone
+                long chrononTime1 = getLong(b1, s1);
+                long chrononTime2 = getLong(b2, s2);
 
-                year = (short) (((b2[s2] & 0xff) << 8) | b2[s2 + 1] & 0xff);
-                time = ((b2[s2 + 4] & 0xff) << 24) | ((b2[s2 + 5] & 0xff) << 16) | ((b2[s2 + 6] & 0xff) << 8)
-                        | (b2[s2 + 7] & 0xff);
+                if (chrononTime1 > chrononTime2) {
+                    return 1;
+                } else if (chrononTime1 < chrononTime2) {
+                    return -1;
+                } else {
+                    return 0;
+                }
+            }
 
-                dt2.setValue(year >> 1, // year
-                        (year & 0x0001) * 8 + ((b2[s2 + 2] >>> 5) & 0x07), // month
-                        b2[s2 + 2] & 0x1f, // day
-                        (short) ((time) * 20 % 216000000 / 3600000), // hour
-                        (short) ((time) * 20 % 3600000 / 60000), // minutes
-                        (short) ((time) * 20 % 60000 / 1000), // seconds
-                        (short) ((time) * 20 % 1000), // milliseconds
-                        0, // microseconds
-                        b2[s2 + 3]); // timezone
-
-                return dt1.compare(dt2);
+            private long getLong(byte[] bytes, int start) {
+                return (((long) (bytes[start] & 0xff)) << 56) + (((long) (bytes[start + 1] & 0xff)) << 48)
+                        + (((long) (bytes[start + 2] & 0xff)) << 40) + (((long) (bytes[start + 3] & 0xff)) << 32)
+                        + (((long) (bytes[start + 4] & 0xff)) << 24) + (((long) (bytes[start + 5] & 0xff)) << 16)
+                        + (((long) (bytes[start + 6] & 0xff)) << 8) + (((long) (bytes[start + 7] & 0xff)) << 0);
             }
 
         };
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 e9f887e..0895630 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
@@ -2,13 +2,17 @@
 
 import java.io.PrintStream;
 
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+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;
 
 public class ADatePrinter implements IPrinter {
 
     private static final long serialVersionUID = 1L;
+
+    private static long CHRONON_OF_DAY = 24 * 60 * 60 * 1000;
+
     public static final ADatePrinter INSTANCE = new ADatePrinter();
 
     @Override
@@ -18,11 +22,23 @@
 
     @Override
     public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
-        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));
+        long chrononTime = AInt32SerializerDeserializer.getInt(b, s + 1) * CHRONON_OF_DAY;
+
+        GregorianCalendarSystem calendar = GregorianCalendarSystem.getInstance();
+
+        int year = calendar.getYear(chrononTime);
+        int month = calendar.getMonthOfYear(chrononTime, year);
+
+        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");
+        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 e3999f1..5fd6905 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
@@ -1,13 +1,11 @@
 package edu.uci.ics.asterix.dataflow.data.nontagged.printers;
 
-import java.io.IOException;
 import java.io.PrintStream;
 
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
-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;
 
 public class ADateTimePrinter implements IPrinter {
 
@@ -21,49 +19,64 @@
 
     @Override
     public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
-        int year = AInt16SerializerDeserializer.getShort(b, s + 1) >> 1;
-        int month = (AInt16SerializerDeserializer.getShort(b, s + 1) & 0x0001) * 8 + ((b[s + 3] >> 5) & 0x07);
+        long chrononTime = AInt64SerializerDeserializer.getLong(b, s + 1);
 
-        int day = b[s + 3] & 0x1f;
-        byte timezone = b[s + 4];
+        GregorianCalendarSystem calendar = GregorianCalendarSystem.getInstance();
 
-        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;
+        int year = calendar.getYear(chrononTime);
+        int month = calendar.getMonthOfYear(chrononTime, year);
 
         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.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("T").append(String.format("%02d", calendar.getHourOfDay(chrononTime))).append(":")
+                .append(String.format("%02d", calendar.getMinOfHour(chrononTime))).append(":")
+                .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 1c4e302..1b141b3 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
@@ -4,6 +4,7 @@
 import java.io.PrintStream;
 
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
 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;
@@ -22,27 +23,28 @@
     public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
         boolean positive = true;
         int months = AInt32SerializerDeserializer.getInt(b, s + 1);
-        int seconds = AInt32SerializerDeserializer.getInt(b, s + 5);
+        long milliseconds = AInt64SerializerDeserializer.getLong(b, s + 5);
 
-        if (months < 0 || seconds < 0) {
+        if (months < 0 || milliseconds < 0) {
             months *= -1;
-            seconds *= -1;
+            milliseconds *= -1;
             positive = false;
         }
 
         int month = (int) (months % 12);
         int year = (int) (months / 12);
-        int second = (int) (seconds % 60);
-        int minute = (int) (seconds % 3600 / 60);
-        int hour = (int) (seconds % (86400) / 3600);
-        int day = (int) (seconds / (86400));
+        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));
 
         ps.print("duration(\"");
         if (!positive) {
             ps.print("-");
         }
         try {
-            ps.print("D");
+            ps.print("P");
             WriteValueTools.writeInt(year, ps);
             ps.print("Y");
             WriteValueTools.writeInt(month, ps);
@@ -54,6 +56,10 @@
             WriteValueTools.writeInt(minute, ps);
             ps.print("M");
             WriteValueTools.writeInt(second, ps);
+            if (millisecond > 0) {
+                ps.print(".");
+                WriteValueTools.writeInt(millisecond, ps);
+            }
             ps.print("S\")");
         } 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 7f687ea..3bbae4a 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
@@ -1,12 +1,11 @@
 package edu.uci.ics.asterix.dataflow.data.nontagged.printers;
 
-import java.io.IOException;
 import java.io.PrintStream;
 
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+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;
 
 public class ATimePrinter implements IPrinter {
 
@@ -21,55 +20,15 @@
     @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();        
         ps.print("time(\"");
-        int timezone = time >> 24;
-        time -= (timezone << 24);
-        printTime(time, timezone, ps);
+        
+        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");
+        
         ps.print("\")");
     }
 
-    final static void printTime(int time, int timezone, PrintStream ps) throws AlgebricksException {
-        int msec = time * 20 % 1000;
-        int sec = time * 20 % 60000 / 1000;
-        int min = time * 20 % 3600000 / 60000;
-        int hour = time * 20 % 216000000 / 3600000;
-        try {
-            if (hour < 10) {
-                ps.print("0");
-            }
-            WriteValueTools.writeInt(hour, ps);
-            ps.print(":");
-            if (min < 10) {
-                ps.print("0");
-            }
-            WriteValueTools.writeInt(min, ps);
-            ps.print(":");
-            if (sec < 10) {
-                ps.print("0");
-            }
-            WriteValueTools.writeInt(sec, ps);
-            ps.print(":");
-            if (msec < 100) {
-                ps.print("0");
-            }
-            if (msec < 10) {
-                ps.print("0");
-            }
-            WriteValueTools.writeInt(msec, ps);
-            ps.print(timezone >= 0 ? "+" : "-");
-            int t1 = Math.abs(timezone / 4);
-            if (t1 < 10) {
-                ps.print("0");
-            }
-            WriteValueTools.writeInt(t1, ps);
-            ps.print(":");
-            int t2 = timezone % 4 * ((timezone >= 0) ? 15 : -15);
-            if (t2 < 10) {
-                ps.print("0");
-            }
-            WriteValueTools.writeInt(t2, ps);
-        } catch (IOException e) {
-            throw new AlgebricksException(e);
-        }
-    }
 }
\ No newline at end of file
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 6a0e8cd..92019e9 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,6 +7,7 @@
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.ADate;
 import edu.uci.ics.asterix.om.base.AMutableDate;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 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;
@@ -14,15 +15,15 @@
 public class ADateSerializerDeserializer implements ISerializerDeserializer<ADate> {
 
     private static final long serialVersionUID = 1L;
-    private short year;
-    private byte monthAndDay;
+
+    private int chrononTimeInDays;
 
     public static final ADateSerializerDeserializer INSTANCE = new ADateSerializerDeserializer();
     @SuppressWarnings("unchecked")
     private static ISerializerDeserializer<ADate> dateSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ADATE);
-    private static AMutableDate aDate = new AMutableDate(0, 0, 0, 0);
-    private static String errorMessage = " can not be an instance of date";
+    private static AMutableDate aDate = new AMutableDate(0);
+    private static final String errorMessage = "This can not be an instance of date";
 
     private ADateSerializerDeserializer() {
     }
@@ -30,10 +31,8 @@
     @Override
     public ADate deserialize(DataInput in) throws HyracksDataException {
         try {
-            year = in.readShort();
-            monthAndDay = in.readByte();
-            return new ADate(year >> 1, (year & 0x0001) * 8 + ((monthAndDay >> 5) & 0x07), monthAndDay & 0x1f,
-                    in.readByte());
+            chrononTimeInDays = in.readInt();
+            return new ADate(chrononTimeInDays);
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
@@ -42,60 +41,215 @@
     @Override
     public void serialize(ADate instance, DataOutput out) throws HyracksDataException {
         try {
-            out.writeByte((byte) ((instance.getYear() << 1) >> 8));
-            out.writeByte((byte) ((byte) ((instance.getYear() << 1) & 0x00ff) + (byte) (instance.getMonth() >> 3)));
-            out.writeByte((byte) (((byte) (instance.getMonth() << 5)) | ((byte) instance.getDay())));
-            out.writeByte((byte) instance.getTimeZone());
+            out.writeInt(instance.getChrononTimeInDays());
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
     }
 
     public static void parse(String date, DataOutput out) throws HyracksDataException {
-        int offset = 0;
-        boolean positive = true;
-        byte timezonePart = 0;
-        if (date.charAt(0) == '-') {
-            positive = false;
-            offset++;
-        }
-
-        if (date.charAt(offset + 4) != '-' || date.charAt(offset + 7) != '-')
-            throw new HyracksDataException(date + errorMessage);
-        short year = Short.parseShort(date.substring(offset, offset + 4));
-        short month = Short.parseShort(date.substring(offset + 5, offset + 7));
-        short day = Short.parseShort(date.substring(offset + 8, offset + 10));
-        short hour, minute;
-        if (year < 0 || year > 9999 || month < 0 || month > 12 || day < 0 || day > 31)
-            throw new HyracksDataException(date + errorMessage);
-
-        offset += 10;
-
-        if (date.length() > offset) {
-            if (date.charAt(offset) == 'Z')
-                timezonePart = 0;
-            else {
-                if ((date.charAt(offset) != '+' && date.charAt(offset) != '-') || (date.charAt(offset + 3) != ':'))
-                    throw new HyracksDataException(date + errorMessage);
-
-                hour = Short.parseShort(date.substring(offset + 1, offset + 3));
-                minute = Short.parseShort(date.substring(offset + 4, offset + 6));
-
-                if (hour < 0 || hour > 24 || (hour == 24 && minute != 0)
-                        || (minute != 0 && minute != 15 && minute != 30 && minute != 45))
-                    throw new HyracksDataException(date + errorMessage);
-
-                if (date.charAt(offset) == '-')
-                    timezonePart = (byte) -((hour * 4) + minute / 15);
-                else
-                    timezonePart = (byte) ((hour * 4) + minute / 15);
-            }
-
-        }
-        if (!positive)
-            year *= -1;
-        aDate.setValue(year, month, day, timezonePart);
+        parseString(date);
         dateSerde.serialize(aDate, out);
     }
 
+    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 = GregorianCalendarSystem.getInstance().getChronon(year, month, day, 0, 0, 0, 0, timezone);
+        aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY));
+        if (chrononTimeInMs < 0 && chrononTimeInMs % GregorianCalendarSystem.CHRONON_OF_DAY != 0)
+            aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY) - 1);
+    }
 }
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 c22da77..975b9d0 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,6 +7,7 @@
 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.types.BuiltinType;
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -19,13 +20,10 @@
     @SuppressWarnings("unchecked")
     private static ISerializerDeserializer<ADateTime> datetimeSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ADATETIME);
-    private static AMutableDateTime aDateTime = new AMutableDateTime(0, 0, 0, 0, 0, 0, 0, 0, 0);
-    private static String errorMessage = " can not be an instance of datetime";
+    private static AMutableDateTime aDateTime = new AMutableDateTime(0L);
+    private static final String errorMessage = "This can not be an instance of datetime";
 
-    private int time;
-    private byte timezone;
-    private short year;
-    private byte monthAndDay;
+    private long chrononTime;
 
     private ADateTimeSerializerDeserializer() {
     }
@@ -33,14 +31,9 @@
     @Override
     public ADateTime deserialize(DataInput in) throws HyracksDataException {
         try {
-            year = in.readShort();
-            monthAndDay = in.readByte();
-            timezone = in.readByte();
-            time = in.readInt();
+            chrononTime = in.readLong();
 
-            return new ADateTime(year >> 1, (year & 0x0001) * 8 + ((monthAndDay >> 5) & 0x07), monthAndDay & 0x1f,
-                    (short) ((time) * 20 % 216000000 / 3600000), (short) ((time) * 20 % 3600000 / 60000),
-                    (short) ((time) * 20 % 60000 / 1000), (short) ((time) * 20 % 1000), (short) 0, timezone);
+            return new ADateTime(chrononTime);
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
@@ -49,92 +42,380 @@
     @Override
     public void serialize(ADateTime instance, DataOutput out) throws HyracksDataException {
         try {
-            out.writeByte((byte) ((instance.getYear() << 1) >> 8));
-            out.writeByte((byte) ((byte) ((instance.getYear() << 1) & 0x00ff) + (byte) (instance.getMonth() >> 3)));
-            out.writeByte((byte) ((instance.getMonth() << 5) | (instance.getDay())));
-            out.writeByte((byte) instance.getTimeZone());
-            out.writeInt((((((instance.getHours() * 60) + instance.getMinutes()) * 60) + instance.getSeconds()) * 1000 + instance
-                    .getMilliseconds()) / 20);
+            out.writeLong(instance.getChrnonoTime());
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
     }
 
     public static void parse(String datetime, DataOutput out) throws HyracksDataException {
-        boolean positive = true;
+        parseString(datetime);
+        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;
-        byte timezonePart = 0;
 
-        if (datetime.charAt(offset) == '-') {
-            offset++;
-            positive = false;
+        boolean positive = true;
+        boolean isExtendedForm = false;
+        if (datetime.charAt(offset + 13) == ':' || datetime.charAt(offset + 14) == ':') {
+            isExtendedForm = true;
         }
-
-        if (datetime.charAt(offset + 4) != '-' || datetime.charAt(offset + 7) != '-')
-            throw new HyracksDataException(datetime + errorMessage);
-
-        short year = Short.parseShort(datetime.substring(offset, offset + 4));
-        short month = Short.parseShort(datetime.substring(offset + 5, offset + 7));
-        short day = Short.parseShort(datetime.substring(offset + 8, offset + 10));
-
-        if (year < 0 || year > 9999 || month < 0 || month > 12 || day < 0 || day > 31)
-            throw new HyracksDataException(datetime + errorMessage);
-
-        if (!positive)
-            year *= -1;
-
-        if (datetime.charAt(offset + 10) != 'T')
-            throw new HyracksDataException(datetime + errorMessage);
-
-        offset += 11;
-
-        if (datetime.charAt(offset + 2) != ':' || datetime.charAt(offset + 5) != ':')
-            throw new HyracksDataException(datetime + errorMessage);
-
-        short hour = Short.parseShort(datetime.substring(offset, offset + 2));
-        short minute = Short.parseShort(datetime.substring(offset + 3, offset + 5));
-        short second = Short.parseShort(datetime.substring(offset + 6, offset + 8));
-        short msecond = 0;
-
-        if (datetime.length() > offset + 8 && datetime.charAt(offset + 8) == ':') {
-            msecond = Short.parseShort(datetime.substring(offset + 9, offset + 12));
-            if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59 || msecond < 0
-                    || msecond > 999 || (hour == 24 && (minute != 0 || second != 0 || msecond != 0)))
-                throw new HyracksDataException(datetime + errorMessage);
-            offset += 12;
-        } else {
-            if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
-                    || (hour == 24 && (minute != 0 || second != 0)))
-                throw new HyracksDataException(datetime + errorMessage);
-            offset += 8;
-        }
-
-        short timezoneHour = 0, timezoneMinute = 0;
-        if (datetime.length() > offset) {
-            if (datetime.charAt(offset) == 'Z')
-                timezonePart = 0;
-            else {
-                if ((datetime.charAt(offset) != '+' && datetime.charAt(offset) != '-')
-                        || (datetime.charAt(offset + 3) != ':'))
-                    throw new HyracksDataException(datetime + errorMessage);
-
-                timezoneHour = Short.parseShort(datetime.substring(offset + 1, offset + 3));
-                timezoneMinute = Short.parseShort(datetime.substring(offset + 4, offset + 6));
-
-                if (timezoneHour < 0
-                        || timezoneHour > 24
-                        || (timezoneHour == 24 && timezoneMinute != 0)
-                        || (timezoneMinute != 0 && timezoneMinute != 15 && timezoneMinute != 30 && timezoneMinute != 45))
-                    throw new HyracksDataException(datetime + errorMessage);
-
-                if (datetime.charAt(offset) == '-')
-                    timezonePart = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                else
-                    timezonePart = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+        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(year, month, day, hour, minute, second, msecond, 0, timezonePart);
-        datetimeSerde.serialize(aDateTime, out);
+
+        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 134eed6..77d757a 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
@@ -29,7 +29,7 @@
     @Override
     public ADuration deserialize(DataInput in) throws HyracksDataException {
         try {
-            return new ADuration(in.readInt(), in.readInt());
+            return new ADuration(in.readInt(), in.readLong());
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
@@ -39,7 +39,7 @@
     public void serialize(ADuration instance, DataOutput out) throws HyracksDataException {
         try {
             out.writeInt(instance.getMonths());
-            out.writeInt(instance.getSeconds());
+            out.writeLong(instance.getMilliseconds());
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
@@ -49,8 +49,8 @@
         try {
             boolean positive = true;
             int offset = 0;
-            int value = 0, hour = 0, minute = 0, second = 0, year = 0, month = 0, day = 0;
-            boolean isYear = true, isMonth = true, isDay = true, isHour = true, isMinute = true, isSecond = true;
+            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) == '-') {
@@ -58,11 +58,12 @@
                 positive = false;
             }
 
-            if (duration.charAt(offset++) != 'D')
+            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)) {
@@ -76,33 +77,21 @@
                         case 'M':
                             if (!isTime) {
                                 if (isMonth) {
-                                    if (value < 0 || value > 11)
-                                        throw new HyracksDataException(duration + errorMessage);
-                                    else {
-                                        month = value;
-                                        isMonth = false;
-                                    }
+                                    month = value;
+                                    isMonth = false;
                                 } else
                                     throw new HyracksDataException(duration + errorMessage);
                             } else if (isMinute) {
-                                if (value < 0 || value > 59)
-                                    throw new HyracksDataException(duration + errorMessage);
-                                else {
-                                    minute = value;
-                                    isMinute = false;
-                                    timeItem = false;
-                                }
+                                minute = value;
+                                isMinute = false;
+                                timeItem = false;
                             } else
                                 throw new HyracksDataException(duration + errorMessage);
                             break;
                         case 'D':
                             if (isDay) {
-                                if (value < 0 || value > 30)
-                                    throw new HyracksDataException(duration + errorMessage);
-                                else {
-                                    day = value;
-                                    isDay = false;
-                                }
+                                day = value;
+                                isDay = false;
                             } else
                                 throw new HyracksDataException(duration + errorMessage);
                             break;
@@ -116,25 +105,25 @@
 
                         case 'H':
                             if (isHour) {
-                                if (value < 0 || value > 23)
-                                    throw new HyracksDataException(duration + errorMessage);
-                                else {
-                                    hour = value;
-                                    isHour = false;
-                                    timeItem = false;
-                                }
+                                hour = value;
+                                isHour = false;
+                                timeItem = false;
                             } else
                                 throw new HyracksDataException(duration + errorMessage);
                             break;
                         case 'S':
                             if (isSecond) {
-                                if (value < 0 || value > 59)
-                                    throw new HyracksDataException(duration + errorMessage);
-                                else {
-                                    second = value;
-                                    isSecond = false;
-                                    timeItem = false;
-                                }
+                                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;
@@ -149,14 +138,18 @@
             if (isTime && timeItem)
                 throw new HyracksDataException(duration + errorMessage);
 
-            if (isYear && isMonth && isDay && !isTime)
-                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 + 3600 * hour + 60 * minute + second);
+                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 + 3600 * hour + 60 * minute + second));
+                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);
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 1d4fe07..81f9327 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,6 +7,7 @@
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AMutableTime;
 import edu.uci.ics.asterix.om.base.ATime;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 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;
@@ -20,10 +21,10 @@
     @SuppressWarnings("unchecked")
     private static ISerializerDeserializer<ATime> timeSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ATIME);
-    private static AMutableTime aTime = new AMutableTime(0, 0, 0, 0, 0, 0);
-    private static String errorMessage = " can not be an instance of time";
+    private static AMutableTime aTime = new AMutableTime(0);
+    private static String errorMessage = "This can not be an instance of time";
 
-    private int time, timezone;
+    private int ora;
 
     private ATimeSerializerDeserializer() {
     }
@@ -31,12 +32,9 @@
     @Override
     public ATime deserialize(DataInput in) throws HyracksDataException {
         try {
-            time = in.readInt();
-            timezone = time >> 24;
-            time -= (timezone << 24);
-            return new ATime((short) ((time << 8 >> 8) * 20 % 216000000 / 3600000),
-                    (short) ((time << 8 >> 8) * 20 % 3600000 / 60000), (short) ((time << 8 >> 8) * 20 % 60000 / 1000),
-                    (short) ((time << 8 >> 8) * 20 % 1000), (short) 0, timezone);
+            ora = in.readInt();
+
+            return new ATime(ora);
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
@@ -45,84 +43,245 @@
     @Override
     public void serialize(ATime instance, DataOutput out) throws HyracksDataException {
         try {
-            time = instance.getTimeZone();
-            time = time << 24;
-            time = time
-                    + ((((((instance.getHours() * 60) + instance.getMinutes()) * 60) + instance.getSeconds()) * 1000 + instance
-                            .getMilliseconds()) / 20);
-            out.writeInt(time);
+            out.writeInt(instance.getOra());
 
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
     }
 
-    public static final void serialize(short hour, short minute, short second, short msecond, byte timeZone,
-            DataOutput out) throws HyracksDataException {
-        try {
-            int time = timeZone;
-            time = time << 24;
-            time = time + ((((((hour * 60) + minute) * 60) + second) * 1000 + msecond) / 20);
-            out.writeInt(time);
-        } catch (IOException e) {
-            throw new HyracksDataException(e);
-        }
-    }
-
     public static void parse(String time, DataOutput out) throws HyracksDataException {
-        try {
-            byte timezonePart = 0;
-            int offset = 0;
-            if (time.charAt(offset + 2) != ':' || time.charAt(offset + 5) != ':')
-                throw new HyracksDataException(time + errorMessage);
+        parseString(time);
+        timeSerde.serialize(aTime, out);
+    }
 
-            short hour = Short.parseShort(time.substring(offset, offset + 2));
-            short minute = Short.parseShort(time.substring(offset + 3, offset + 5));
-            short second = Short.parseShort(time.substring(offset + 6, offset + 8));
-            short msecond = 0;
-            if (time.length() > offset + 8 && time.charAt(offset + 8) == ':') {
-                msecond = Short.parseShort(time.substring(offset + 9, offset + 12));
-                if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59 || msecond < 0
-                        || msecond > 999 || (hour == 24 && (minute != 0 || second != 0 || msecond != 0)))
-                    throw new HyracksDataException(time + errorMessage);
-                offset += 12;
-            } else {
-                if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
-                        || (hour == 24 && (minute != 0 || second != 0)))
-                    throw new HyracksDataException(time + errorMessage);
-                offset += 8;
+    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);
+
             }
 
-            short timezoneHour = 0, timezoneMinute = 0;
-            if (time.length() > offset) {
-                if (time.charAt(offset) == 'Z')
-                    timezonePart = 0;
-                else {
-                    if ((time.charAt(offset) != '+' && time.charAt(offset) != '-') || (time.charAt(offset + 3) != ':'))
-                        throw new HyracksDataException(time + errorMessage);
+            if (hour < 0 || hour > 23) {
+                throw new HyracksDataException(errorMessage + ": hour " + hour);
+            }
 
-                    timezoneHour = Short.parseShort(time.substring(offset + 1, offset + 3));
-                    timezoneMinute = Short.parseShort(time.substring(offset + 4, offset + 6));
+            offset += 3;
 
-                    if (timezoneHour < 0
-                            || timezoneHour > 24
-                            || (timezoneHour == 24 && timezoneMinute != 0)
-                            || (timezoneMinute != 0 && timezoneMinute != 15 && timezoneMinute != 30 && timezoneMinute != 45))
-                        throw new HyracksDataException(time + errorMessage);
+            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 (time.charAt(offset) == '-')
-                        timezonePart = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                    else
-                        timezonePart = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+            }
+
+            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;
+                    }
+                }
             }
 
-            aTime.setValue(hour, minute, second, msecond, 0, timezonePart);
+            if (time.length() > offset) {
+                if (time.charAt(offset) != 'Z') {
+                    if ((time.charAt(offset) != '+' && time.charAt(offset) != '-') || (time.charAt(offset + 3) != ':'))
+                        throw new HyracksDataException(errorMessage);
 
-            timeSerde.serialize(aTime, out);
-        } catch (HyracksDataException e) {
-            throw new HyracksDataException(time + 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 f60c908..0eefc98 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
@@ -1,38 +1,22 @@
 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;
 
+/**
+ * ADate type represents dates in a gregorian calendar system.
+ */
 public class ADate implements IAObject {
 
-    protected int day;
-    protected int month;
-    protected int year;
-    protected int timezone;
+    protected int chrononTimeInDay;
 
-    public ADate(int year, int month, int day, int timezone) {
-        this.day = day;
-        this.month = month;
-        this.year = year;
-        this.timezone = timezone;
-    }
+    private static long CHRONON_OF_DAY = 24 * 60 * 60 * 1000;
 
-    public int getDay() {
-        return day;
-    }
-
-    public int getMonth() {
-        return month;
-    }
-
-    public int getTimeZone() {
-        return timezone;
-    }
-
-    public int getYear() {
-        return year;
+    public ADate(int chrononTimeInDay) {
+        this.chrononTimeInDay = chrononTimeInDay;
     }
 
     public IAType getType() {
@@ -43,14 +27,13 @@
         if (!(o instanceof ADate)) {
             return false;
         } else {
-            ADate d = (ADate) o;
-            return d.getDay() == day && d.getMonth() == month && d.getYear() == year && d.getTimeZone() == timezone;
+            return ((ADate) o).chrononTimeInDay == this.chrononTimeInDay;
         }
     }
 
     @Override
     public int hashCode() {
-        return ((year * 31 + month) * 31 + day) * 31 + timezone;
+        return chrononTimeInDay;
     }
 
     @Override
@@ -70,6 +53,15 @@
 
     @Override
     public String toString() {
-        return "ADate: { " + year + "-" + month + "-" + day + ":" + timezone + " }";
+        StringBuilder sbder = new StringBuilder();
+        sbder.append("ADate: { ");
+        GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(
+                chrononTimeInDay * CHRONON_OF_DAY, 0, sbder, GregorianCalendarSystem.YEAR, GregorianCalendarSystem.DAY);
+        sbder.append(" }");
+        return sbder.toString();
+    }
+
+    public int getChrononTimeInDays() {
+        return chrononTimeInDay;
     }
 }
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 e300d78..a410bed 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
@@ -1,73 +1,39 @@
 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;
 
+/**
+ * ADateTime type represents the timestamp values.
+ * <p/>
+ * An ADateTime value contains the following time fields:<br/>
+ * - year;<br/>
+ * - month;<br/>
+ * - day;<br/>
+ * - hour; <br/>
+ * - minute; <br/>
+ * - second; <br/>
+ * - millisecond. <br/>
+ * By default, an ADateTime value is a UTC time value, i.e., there is no timezone information maintained. However user can use the timezone based AQL function to convert a UTC time to a timezone-embedded time.
+ * <p/>
+ * And the string representation of an ADateTime value follows the ISO8601 standard, in the following format:<br/>
+ * [+|-]YYYY-MM-DDThh:mm:ss.xxxZ
+ * <p/>
+ * Internally, an ADateTime value is stored as the number of milliseconds elapsed since 1970-01-01T00:00:00.000Z (also called chronon time). Functions to convert between a string representation of an ADateTime and its chronon time are implemented in {@link GregorianCalendarSystem}.
+ * <p/>
+ */
 public class ADateTime implements IAObject {
 
-    private static final int[] NUM_DAYS_IN_MONTH = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+    /**
+     * Represent the time interval as milliseconds since 1970-01-01T00:00:00.000Z.
+     */
+    protected long chrononTime;
 
-    protected int day;
-    protected int hour;
-    protected int minutes;
-    protected int month;
-    protected int seconds;
-    protected int timezone;
-    protected int year;
-    protected int milliseconds;
-    protected int microseconds;
-
-    public ADateTime(int year, int month, int day, int hour, int minutes, int seconds, int timezone) {
-        this.year = year;
-        this.month = month;
-        this.day = day;
-        this.hour = hour;
-        this.minutes = minutes;
-        this.seconds = seconds;
-        this.timezone = timezone;
-    }
-
-    public ADateTime(int year, int month, int day, int hour, int minutes, int seconds, int milliseconds,
-            int microseconds, int timezone) {
-        this.year = year;
-        this.month = month;
-        this.day = day;
-        this.hour = hour;
-        this.minutes = minutes;
-        this.seconds = seconds;
-        this.milliseconds = milliseconds;
-        this.microseconds = microseconds;
-        this.timezone = timezone;
-    }
-
-    public int getDay() {
-        return day;
-    }
-
-    public int getHours() {
-        return hour;
-    }
-
-    public int getMinutes() {
-        return minutes;
-    }
-
-    public int getMonth() {
-        return month;
-    }
-
-    public int getSeconds() {
-        return seconds;
-    }
-
-    public int getTimeZone() {
-        return timezone;
-    }
-
-    public int getYear() {
-        return year;
+    public ADateTime(long chrononTime) {
+        this.chrononTime = chrononTime;
     }
 
     @Override
@@ -75,125 +41,33 @@
         return BuiltinType.ADATETIME;
     }
 
-    public int getMicroseconds() {
-        return microseconds;
-    }
-
-    public int getMilliseconds() {
-        return milliseconds;
-    }
-
     public int compare(Object o) {
         if (!(o instanceof ADateTime)) {
             return -1;
         }
 
         ADateTime d = (ADateTime) o;
-        if (timezone != d.getTimeZone()) {
-            AMutableDateTime dt1 = new AMutableDateTime(year, month, day, hour, minutes, seconds, milliseconds,
-                    microseconds, timezone);
-            AMutableDateTime dt2 = new AMutableDateTime(d.getYear(), d.getMonth(), d.getDay(), d.getHours(),
-                    d.getMinutes(), d.getSeconds(), d.getMilliseconds(), d.getMicroseconds(), d.getTimeZone());
-            dt1.convertToUTC();
-            dt2.convertToUTC();
-
-            return dt1.tzEqualCompare(dt2);
-
-        }
-
-        return tzEqualCompare(d);
-    }
-
-    protected void convertToUTC() {
-        short tzMin = (short) ((timezone % 4) * 15);
-        short tzHr = (short) (timezone / 4);
-        minutes -= tzMin;
-        if (minutes >= 60) {
-            minutes %= 60;
-            hour += 1;
-        }
-        hour -= tzHr;
-        if (hour >= 24) {
-            hour %= 24;
-            day += 1;
-        }
-        if (isLeapYear(year) && month == 2) {
-            if (day >= 29) {
-                day %= 29;
-                month += 1;
-            }
+        if (this.chrononTime > d.chrononTime) {
+            return 1;
+        } else if (this.chrononTime < d.chrononTime) {
+            return -1;
         } else {
-            if (day >= NUM_DAYS_IN_MONTH[month - 1]) {
-                day %= NUM_DAYS_IN_MONTH[month - 1];
-                month += 1;
-            }
+            return 0;
         }
-
-        if (month >= 12) {
-            month %= 12;
-            year += 1;
-        }
-        timezone = 0;
-
-    }
-
-    protected static boolean isLeapYear(int year) {
-        if (year % 400 == 0) {
-            return true;
-        } else if (year % 100 == 0) {
-            return false;
-        } else if (year % 4 == 0) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    // comparison that assumes the timezones are the same!
-    protected int tzEqualCompare(ADateTime d) {
-        if (year != d.getYear()) {
-            return year - d.getYear();
-        }
-        if (month != d.getMonth()) {
-            return month - d.getMonth();
-        }
-        if (day != d.getDay()) {
-            return day - d.getDay();
-        }
-        if (hour != d.getHours()) {
-            return hour - d.getHours();
-        }
-        if (minutes != d.getMinutes()) {
-            return minutes - d.getMinutes();
-        }
-        if (seconds != d.getSeconds()) {
-            return seconds - d.getSeconds();
-        }
-        if (milliseconds != d.getMilliseconds()) {
-            return milliseconds - d.getMilliseconds();
-        }
-        if (microseconds != d.getMicroseconds()) {
-            return microseconds - d.getMicroseconds();
-        }
-
-        return 0;
     }
 
     public boolean equals(Object o) {
         if (!(o instanceof ADateTime)) {
             return false;
         } else {
-            ADateTime d = (ADateTime) o;
-            return d.getMicroseconds() == microseconds && d.getMilliseconds() == milliseconds
-                    && d.getSeconds() == seconds && d.getMinutes() == minutes && d.getHours() == hour
-                    && d.getDay() == day && d.getMonth() == month && d.getYear() == year && d.getTimeZone() == timezone;
+            ADateTime t = (ADateTime) o;
+            return t.chrononTime == this.chrononTime;
         }
     }
 
     @Override
     public int hashCode() {
-        return (((((((year * 31 + month) * 31 + day) * 31 + timezone) * 31 + hour) * 31 + minutes) * 31 + seconds) * 31 + milliseconds)
-                * 31 + microseconds;
+        return (int) (chrononTime ^ (chrononTime >>> 32));
     }
 
     @Override
@@ -213,8 +87,16 @@
 
     @Override
     public String toString() {
-        return "ADateTime: { " + year + "-" + month + "-" + day + ":" + hour + ":" + minutes + ":" + seconds + ":"
-                + milliseconds + ":" + microseconds + ":" + timezone + " }";
+        StringBuilder sbder = new StringBuilder();
+        sbder.append("ADateTime: { ");
+        GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(chrononTime, 0, sbder,
+                GregorianCalendarSystem.YEAR, GregorianCalendarSystem.MILLISECOND);
+        sbder.append(" }");
+        return sbder.toString();
+    }
+
+    public long getChrnonoTime() {
+        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 6f8064e..7c60822 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
@@ -7,20 +7,20 @@
 
 public class ADuration implements IAObject {
 
-    protected int months;
-    protected int seconds;
+    protected int chrononInMonth;
+    protected long chrononInMillisecond;
 
-    public ADuration(int months, int seconds) {
-        this.months = months;
-        this.seconds = seconds;
+    public ADuration(int months, long seconds) {
+        this.chrononInMonth = months;
+        this.chrononInMillisecond = seconds;
     }
 
     public int getMonths() {
-        return months;
+        return chrononInMonth;
     }
 
-    public int getSeconds() {
-        return seconds;
+    public long getMilliseconds() {
+        return chrononInMillisecond;
     }
 
     @Override
@@ -34,13 +34,13 @@
             return false;
         } else {
             ADuration d = (ADuration) o;
-            return d.getMonths() == months && d.getSeconds() == seconds;
+            return d.getMonths() == chrononInMonth && d.getMilliseconds() == chrononInMillisecond;
         }
     }
 
     @Override
     public int hashCode() {
-        return months * 31 + seconds;
+        return (int) (chrononInMonth ^ (chrononInMillisecond) ^ (chrononInMillisecond >>> 32));
     }
 
     @Override
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDate.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDate.java
index 78a87b8..f6a8e2d 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDate.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDate.java
@@ -2,15 +2,12 @@
 
 public class AMutableDate extends ADate {
 
-    public AMutableDate(int year, int month, int day, int timezone) {
-        super(year, month, day, timezone);
+    public AMutableDate(int chrononTimeInDays) {
+        super(chrononTimeInDays);
     }
 
-    public void setValue(int year, int month, int day, int timezone) {
-        this.year = year;
-        this.month = month;
-        this.day = day;
-        this.timezone = timezone;
+    public void setValue(int chrononTimeInDays) {
+        this.chrononTimeInDay = chrononTimeInDays;
     }
 
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDateTime.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDateTime.java
index 01e30a2..88553b0 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDateTime.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDateTime.java
@@ -2,22 +2,12 @@
 
 public class AMutableDateTime extends ADateTime {
 
-    public AMutableDateTime(int year, int month, int day, int hour, int minutes, int seconds, int milliseconds,
-            int microseconds, int timezone) {
-        super(year, month, day, hour, minutes, seconds, milliseconds, microseconds, timezone);
+    public AMutableDateTime(long chrononTime) {
+        super(chrononTime);
     }
 
-    public void setValue(int year, int month, int day, int hour, int minutes, int seconds, int milliseconds,
-            int microseconds, int timezone) {
-        this.year = year;
-        this.month = month;
-        this.day = day;
-        this.hour = hour;
-        this.minutes = minutes;
-        this.seconds = seconds;
-        this.milliseconds = milliseconds;
-        this.microseconds = microseconds;
-        this.timezone = timezone;
+    public void setValue(long chrononTime) {
+        this.chrononTime = chrononTime;
     }
 
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDuration.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDuration.java
index f776817..367d529 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDuration.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableDuration.java
@@ -2,13 +2,13 @@
 
 public class AMutableDuration extends ADuration {
 
-    public AMutableDuration(int months, int seconds) {
-        super(months, seconds);
+    public AMutableDuration(int months, long milliseconds) {
+        super(months, milliseconds);
     }
 
-    public void setValue(int months, int seconds) {
-        this.months = months;
-        this.seconds = seconds;
+    public void setValue(int months, long milliseconds) {
+        this.chrononInMonth = months;
+        this.chrononInMillisecond = milliseconds;
     }
 
 }
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 a23b8e3..277479f 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,16 +2,12 @@
 
 public class AMutableTime extends ATime {
 
-    public AMutableTime(int hour, int minutes, int seconds, int milliseconds, int microseconds, int timezone) {
-        super(hour, minutes, seconds, milliseconds, microseconds, timezone);
+    public AMutableTime(int ora) {
+        super(ora);
     }
 
-    public void setValue(int hour, int minutes, int seconds, int milliseconds, int microseconds, int timezone) {
-        this.hour = hour;
-        this.minutes = minutes;
-        this.seconds = seconds;
-        this.milliseconds = milliseconds;
-        this.timezone = timezone;
+    public void setValue(int ora) {
+        this.chrononTime = ora;
     }
 
 }
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 f948ffc..7f6cc1e 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
@@ -1,49 +1,17 @@
 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;
 
 public class ATime implements IAObject {
 
-    protected int hour;
-    protected int minutes;
-    protected int seconds;
-    protected int timezone;
-    protected int milliseconds;
-    protected int microseconds;
+    protected int chrononTime;
 
-    public ATime(int hour, int minutes, int seconds, int timezone) {
-        this.hour = hour;
-        this.minutes = minutes;
-        this.seconds = seconds;
-        this.timezone = timezone;
-    }
-
-    public ATime(int hour, int minutes, int seconds, int milliseconds, int microseconds, int timezone) {
-        this.hour = hour;
-        this.minutes = minutes;
-        this.seconds = seconds;
-        this.milliseconds = milliseconds;
-        this.microseconds = microseconds;
-        this.timezone = timezone;
-    }
-
-    public int getHours() {
-        return hour;
-    }
-
-    public int getMinutes() {
-        return minutes;
-    }
-
-    public int getSeconds() {
-        return seconds;
-    }
-
-    public int getTimeZone() {
-        return timezone;
+    public ATime(int ora) {
+        this.chrononTime = ora;
     }
 
     @Override
@@ -51,29 +19,36 @@
         return BuiltinType.ATIME;
     }
 
-    public int getMicroseconds() {
-        return microseconds;
-    }
+    public int compare(Object o) {
+        if (!(o instanceof ATime)) {
+            return -1;
+        }
 
-    public int getMilliseconds() {
-        return milliseconds;
+        ATime d = (ATime) o;
+        if (this.chrononTime > d.chrononTime) {
+            return 1;
+        } else if (this.chrononTime < d.chrononTime) {
+            return -1;
+        } else {
+            return 0;
+        }
     }
 
     @Override
     public boolean equals(Object o) {
+
         if (!(o instanceof ATime)) {
             return false;
         } else {
             ATime t = (ATime) o;
-            return t.getMicroseconds() == microseconds && t.getMilliseconds() == milliseconds
-                    && t.getSeconds() == seconds && t.getMinutes() == minutes && t.getHours() == hour
-                    && t.getTimeZone() == timezone;
+            return t.chrononTime == this.chrononTime;
+
         }
     }
 
     @Override
     public int hashCode() {
-        return ((((timezone * 31 + hour) * 31 + minutes) * 31 + seconds) * 31 + milliseconds) * 31 + microseconds;
+        return chrononTime;
     }
 
     @Override
@@ -93,7 +68,17 @@
 
     @Override
     public String toString() {
-        return "ATime: { " + hour + ":" + minutes + ":" + seconds + ":" + milliseconds + ":" + microseconds + ":"
-                + timezone + " }";
+        StringBuilder sbder = new StringBuilder();
+        sbder.append("ATime: { ");
+        GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(chrononTime, 0, sbder,
+                GregorianCalendarSystem.HOUR, GregorianCalendarSystem.MILLISECOND);
+        sbder.append(" }");
+        return sbder.toString();
+
     }
+
+    public int getOra() {
+        return chrononTime;
+    }
+
 }
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
new file mode 100644
index 0000000..d23773f
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
@@ -0,0 +1,552 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Joda API (http://joda-time.sourceforge.net/) is under the protection of:
+ * 
+ * Copyright 2001-2005 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.base.temporal;
+
+/**
+ * A simple implementation of the Gregorian calendar system.
+ * <p/>
+ */
+public class GregorianCalendarSystem implements ICalendarSystem {
+
+    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 };
+
+    public static final int[] DAYS_SINCE_MONTH_BEGIN_ORDI = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+
+    public static final int CHRONON_OF_SECOND = 1000;
+    public static final int CHRONON_OF_MINUTE = 60 * CHRONON_OF_SECOND;
+    public static final int CHRONON_OF_HOUR = 60 * CHRONON_OF_MINUTE;
+    public static final long CHRONON_OF_DAY = 24 * CHRONON_OF_HOUR;
+
+    /**
+     * Minimum feasible value of each field
+     */
+    public static final int[] FIELD_MINS = { Integer.MIN_VALUE, // year
+            1, // month
+            1, // day
+            0, // hour
+            0, // minute
+            0, // second
+            0 // millisecond
+    };
+
+    public static final int[] FIELD_MAXS = { Integer.MAX_VALUE, // year
+            12, // month
+            31, // day
+            23, // hour
+            59, // minute
+            59, // second
+            999 // millisecond
+    };
+
+    public static final int TIMEZONE_HOUR_MIN = -12, TIMEZONE_HOUR_MAX = 14, TIMEZONE_MIN_MIN = -60,
+            TIMEZONE_MIN_MAX = 60;
+
+    /**
+     * From Joda API: GregorianChronology.java
+     */
+    private static final long CHRONON_OF_YEAR = (long) (365.2425 * CHRONON_OF_DAY);
+
+    /**
+     * From Joda API: GregorianChronology.java
+     */
+    private static final int DAYS_0000_TO_1970 = 719527;
+
+    private static final GregorianCalendarSystem instance = new GregorianCalendarSystem();
+
+    private GregorianCalendarSystem() {
+    }
+
+    public static GregorianCalendarSystem getInstance() {
+        return instance;
+    }
+
+    /**
+     * Check whether the given date time value is a valid date time following the gregorian calendar system.
+     * 
+     * @param fields
+     * @return
+     */
+    public boolean validate(int year, int month, int day, int hour, int min, int sec, int millis) {
+        // Check whether each field is within the value domain
+        if (year < FIELD_MINS[0] || year > FIELD_MAXS[0])
+            return false;
+        if (month < FIELD_MINS[1] || month > FIELD_MAXS[1])
+            return false;
+        if (day < FIELD_MINS[2] || day > FIELD_MAXS[2])
+            return false;
+        if (hour < FIELD_MINS[3] || hour > FIELD_MAXS[3])
+            return false;
+        if (min < FIELD_MINS[4] || min > FIELD_MAXS[4])
+            return false;
+        if (sec < FIELD_MINS[5] || sec > FIELD_MAXS[5])
+            return false;
+        if (millis < FIELD_MINS[6] || millis > FIELD_MAXS[6])
+            return false;
+
+        // Check whether leap month.
+        if (month == 2)
+            if (isLeapYear(year)) {
+                if (month > DAYS_OF_MONTH_LEAP[1])
+                    return false;
+            } else {
+                if (month > DAYS_OF_MONTH_ORDI[1])
+                    return false;
+            }
+        return true;
+    }
+
+    /**
+     * Check whether the given time zone value is a valid time zone following the gregorian calendar system.
+     * 
+     * @param timezone
+     * @return
+     */
+    public boolean validateTimeZone(int timezone) {
+        short tzMin = (short) ((timezone % 4) * 15);
+
+        if (tzMin < -60 || tzMin >= 60) {
+            return false;
+        }
+
+        short tzHr = (short) (timezone / 4);
+
+        if (tzHr < -12 && tzHr > 14) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Validate the given chronon time and time zone.
+     * 
+     * @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) {
+        return validate(year, month, day, hour, min, sec, millis) && validateTimeZone(timezone);
+    }
+
+    /**
+     * Get the UTC chronon time of the given date time and time zone.
+     * 
+     * @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) {
+        // Added milliseconds for all fields but month and day
+        long chrononTime = chrononizeBeginningOfYear(year) + (hour - timezone / 4) * CHRONON_OF_HOUR
+                + (min - (timezone % 4) * 15) * CHRONON_OF_MINUTE + sec * CHRONON_OF_SECOND + millis;
+
+        // Added milliseconds for days of the month. 
+        chrononTime += (day - 1 + DAYS_SINCE_MONTH_BEGIN_ORDI[month - 1]) * CHRONON_OF_DAY;
+
+        // Adjust the leap year
+        if (month > 2 && isLeapYear(year)) {
+            chrononTime += CHRONON_OF_DAY;
+        }
+
+        return chrononTime;
+    }
+
+    /**
+     * Get the chronon time (number of milliseconds) of the given time and time zone.
+     * 
+     * @param hour
+     * @param min
+     * @param sec
+     * @param millis
+     * @param timezone
+     * @return
+     */
+    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;
+    }
+
+    /**
+     * Get the extended string representation of the given UTC chronon time under the given time zone. Only fields before
+     * the given field index will be returned.
+     * <p/>
+     * The extended string representation is like:<br/>
+     * [-]YYYY-MM-DDThh:mm:ss.xxx[Z|[+|-]hh:mm]
+     * 
+     * @param chrononTime
+     * @param timezone
+     * @param sbder
+     * @param untilField
+     */
+    public void getExtendStringRepWithTimezoneUntilField(long chrononTime, int timezone, StringBuilder sbder,
+            int startField, int 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) {
+                    return;
+                }
+            case MONTH:
+                if (startField != MONTH)
+                    sbder.append("-");
+                sbder.append(String.format("%02d", month));
+                if (untilField == MONTH) {
+                    return;
+                }
+            case DAY:
+                if (startField != DAY)
+                    sbder.append("-");
+                sbder.append(String.format("%02d", getDayOfMonthYear(chrononTime, year, month)));
+                if (untilField == DAY) {
+                    break;
+                }
+            case HOUR:
+                if (startField != HOUR)
+                    sbder.append("T");
+                sbder.append(String.format("%02d", getHourOfDay(chrononTime)));
+                if (untilField == HOUR) {
+                    break;
+                }
+            case MINUTE:
+                if (startField != MINUTE)
+                    sbder.append(":");
+                sbder.append(String.format("%02d", getMinOfHour(chrononTime)));
+                if (untilField == MINUTE) {
+                    break;
+                }
+            case SECOND:
+                if (startField != SECOND)
+                    sbder.append(":");
+                sbder.append(String.format("%02d", getSecOfMin(chrononTime)));
+                // add millisecond as the precision fields of a second
+                sbder.append(".").append(String.format("%03d", getMillisOfSec(chrononTime)));
+                break;
+        }
+
+        if (timezone == 0) {
+            sbder.append("Z");
+        } else {
+            short tzMin = (short) ((timezone % 4) * 15);
+            short tzHr = (short) (timezone / 4);
+            sbder.append((tzHr >= 0 ? "+" : "-")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr))).append(":")
+                    .append(String.format("%02d", tzMin));
+        }
+    }
+
+    /**
+     * Get the basic string representation of a chronon time with the given time zone.
+     * 
+     * @param chrononTime
+     * @param timezone
+     * @param sbder
+     */
+    public void getBasicStringRepWithTimezoneUntiField(long chrononTime, int timezone, StringBuilder sbder,
+            int startField, int 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) {
+                    return;
+                }
+            case MONTH:
+                sbder.append(String.format("%02d", month));
+                if (untilField == MONTH) {
+                    return;
+                }
+            case DAY:
+                sbder.append(String.format("%02d", getDayOfMonthYear(chrononTime, year, month)));
+                if (untilField == DAY) {
+                    break;
+                }
+            case HOUR:
+                sbder.append(String.format("%02d", getHourOfDay(chrononTime)));
+                if (untilField == HOUR) {
+                    break;
+                }
+            case MINUTE:
+                sbder.append(String.format("%02d", getMinOfHour(chrononTime)));
+                if (untilField == MINUTE) {
+                    break;
+                }
+            case SECOND:
+                sbder.append(String.format("%02d", getSecOfMin(chrononTime)));
+                // add millisecond as the precision fields of a second
+                sbder.append(String.format("%03d", getMillisOfSec(chrononTime)));
+                break;
+        }
+
+        if (timezone == 0) {
+            sbder.append("Z");
+        } else {
+            short tzMin = (short) ((timezone % 4) * 15);
+            short tzHr = (short) (timezone / 4);
+            sbder.append((tzHr >= 0 ? "+" : "-")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
+                    .append(String.format("%02d", tzMin));
+        }
+    }
+
+    /**
+     * Check whether a given year is a leap year.
+     * 
+     * @param year
+     * @return
+     */
+    protected boolean isLeapYear(int year) {
+        return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
+    }
+
+    /**
+     * From Joda library GregorianChronology class: The basic calculation is
+     * (y / 4) - (y / 100) + (y / 400). <br/>
+     * Use y >> 2 ( (y + 3) >> 2 for negative y value) to replace y / 4 reveals eliminates two divisions.
+     * 
+     * @param year
+     * @return
+     */
+    private long chrononizeBeginningOfYear(int year) {
+        int leapYears = year / 100;
+        if (year < 0) {
+            // From Joda library GregorianChronology class
+            // The basic calculation is (y / 4) - (y / 100) + (y / 400)
+            // Use (y + 3) >> 2 to replace y / 4 reveals eliminates two divisions.
+            leapYears = ((year + 3) >> 2) - leapYears + ((leapYears + 3) >> 2) - 1;
+        } else {
+            leapYears = (year >> 2) - leapYears + (leapYears >> 2);
+            if (isLeapYear(year)) {
+                leapYears--;
+            }
+        }
+        return (year * 365L + (leapYears - DAYS_0000_TO_1970)) * CHRONON_OF_DAY;
+    }
+
+    /**
+     * Get the year for the given chronon time.
+     * <p/>
+     * This code is directly from the Joda library BadicChronology.java.<br/>
+     * The original authers are Stephen Colebourne, Brain S O'Neill and Guy Allard, and modified by JArod Wen on May 7th, 2012.
+     * 
+     * @param chrononTime
+     * @return
+     */
+    public int getYear(long chrononTime) {
+        // Get an initial estimate of the year, and the millis value that
+        // represents the start of that year. Then verify estimate and fix if
+        // necessary.
+
+        // Initial estimate uses values divided by two to avoid overflow.
+        long unitMillis = CHRONON_OF_YEAR / 2;
+        long i2 = (chrononTime >> 1) + (1970L * CHRONON_OF_YEAR) / 2;
+        if (i2 < 0) {
+            i2 = i2 - unitMillis + 1;
+        }
+        int year = (int) (i2 / unitMillis);
+
+        long yearStart = chrononizeBeginningOfYear(year);
+        long diff = chrononTime - yearStart;
+
+        if (diff < 0) {
+            year--;
+        } else if (diff >= CHRONON_OF_DAY * 365L) {
+            // One year may need to be added to fix estimate.
+            long oneYear;
+            if (isLeapYear(year)) {
+                oneYear = CHRONON_OF_DAY * 366L;
+            } else {
+                oneYear = CHRONON_OF_DAY * 365L;
+            }
+
+            yearStart += oneYear;
+
+            if (yearStart <= chrononTime) {
+                // Didn't go too far, so actually add one year.
+                year++;
+            }
+        }
+
+        return year;
+    }
+
+    /**
+     * Get the month of the year for the given chronon time and the year.
+     * <p/>
+     * This code is directly from the Joda library BasicGJChronology.java.<br/>
+     * The original authers are Stephen Colebourne, Brain S O'Neill and Guy Allard, and modified by JArod Wen on May 7th, 2012.
+     * <p/>
+     * 
+     * @param millis
+     * @param year
+     * @return
+     */
+    public int getMonthOfYear(long millis, int year) {
+        // Perform a binary search to get the month. To make it go even faster,
+        // compare using ints instead of longs. The number of milliseconds per
+        // year exceeds the limit of a 32-bit int's capacity, so divide by
+        // 1024. No precision is lost (except time of day) since the number of
+        // milliseconds per day contains 1024 as a factor. After the division,
+        // the instant isn't measured in milliseconds, but in units of
+        // (128/125)seconds.
+
+        int i = (int) ((millis - chrononizeBeginningOfYear(year)) >> 10);
+
+        // There are 86400000 milliseconds per day, but divided by 1024 is
+        // 84375. There are 84375 (128/125)seconds per day.
+
+        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
+                        : (i < 335 * 84375) ? 11 : 12)))
+                : ((i < 181 * 84375) ? ((i < 90 * 84375) ? ((i < 31 * 84375) ? 1 : (i < 59 * 84375) ? 2 : 3)
+                        : ((i < 120 * 84375) ? 4 : (i < 151 * 84375) ? 5 : 6))
+                        : ((i < 273 * 84375) ? ((i < 212 * 84375) ? 7 : (i < 243 * 84375) ? 8 : 9)
+                                : ((i < 304 * 84375) ? 10 : (i < 334 * 84375) ? 11 : 12)));
+    }
+
+    /**
+     * Get the day of the given month and year for the input chronon time.
+     * <p/>
+     * This function is directly from Joda Library BasicChronology.java.<br/>
+     * The original authers are Stephen Colebourne, Brain S O'Neill and Guy Allard, and modified by JArod Wen on May 7th, 2012.
+     * <p/>
+     * 
+     * @param millis
+     * @param year
+     * @param month
+     * @return
+     */
+    public int getDayOfMonthYear(long millis, int year, int month) {
+        long dateMillis = chrononizeBeginningOfYear(year);
+        dateMillis += DAYS_SINCE_MONTH_BEGIN_ORDI[month - 1] * CHRONON_OF_DAY;
+        if (isLeapYear(year) && month > 2) {
+            dateMillis += CHRONON_OF_DAY;
+        }
+        return (int) ((millis - dateMillis) / CHRONON_OF_DAY) + 1;
+    }
+
+    /**
+     * Get the hour of the day for the given chronon time.
+     * 
+     * @param millis
+     * @return
+     */
+    public int getHourOfDay(long millis) {
+        int hour = (int) ((millis % CHRONON_OF_DAY) / CHRONON_OF_HOUR);
+
+        if (millis < 0) {
+            if (millis % CHRONON_OF_HOUR == 0) {
+                if (hour < 0) {
+                    hour += 24;
+                }
+            } else {
+                hour += 23;
+            }
+        }
+
+        return hour;
+    }
+
+    /**
+     * Get the minute of the hour for the given chronon time.
+     * 
+     * @param millis
+     * @return
+     */
+    public int getMinOfHour(long millis) {
+        int min = (int) ((millis % CHRONON_OF_HOUR) / CHRONON_OF_MINUTE);
+        if (millis < 0) {
+            if (millis % CHRONON_OF_MINUTE == 0) {
+                if (min < 0) {
+                    min += 60;
+                }
+            } else {
+                min += 59;
+            }
+        }
+        return min;
+    }
+
+    /**
+     * Get the second of the minute for the given chronon time.
+     * 
+     * @param millis
+     * @return
+     */
+    public int getSecOfMin(long millis) {
+        int sec = (int) ((millis % CHRONON_OF_MINUTE) / CHRONON_OF_SECOND);
+        if (millis < 0) {
+            if (millis % CHRONON_OF_SECOND == 0) {
+                if (sec < 0) {
+                    sec += 60;
+                }
+            } else {
+                sec += 59;
+            }
+        }
+        return sec;
+    }
+
+    /**
+     * Get the millisecond of the second for the given chronon time.
+     * 
+     * @param millis
+     * @return
+     */
+    public int getMillisOfSec(long millis) {
+        int ms = (int) (millis % CHRONON_OF_SECOND);
+        if (millis < 0 && ms < 0) {
+            ms += 1000;
+        }
+        return ms;
+    }
+}
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
new file mode 100644
index 0000000..410b73a
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICalendarSystem.java
@@ -0,0 +1,15 @@
+package edu.uci.ics.asterix.om.base.temporal;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+
+public interface ICalendarSystem {
+
+    public boolean validate(int year, int month, int day, int hour, int min, int sec, int millis, int timezone);
+
+    public long getChronon(int year, int month, int day, int hour, int min, int sec, int millis, int timezone);
+
+    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/util/NonTaggedFormatUtil.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/NonTaggedFormatUtil.java
index e1eaa7c..712843a 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/NonTaggedFormatUtil.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/NonTaggedFormatUtil.java
@@ -90,8 +90,9 @@
             case INT64:
             case DOUBLE:
             case DATETIME:
-            case DURATION:
                 return 8;
+            case DURATION:
+                return 12;
             case POINT:
                 return 16;
             case POINT3D:
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 cfbddf5..3a28805 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,7 @@
 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.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -48,11 +49,8 @@
                     private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval = args[0].createEvaluator(outInput);
                     private int offset;
-                    private short year, month, day, hour, minute, value;
-                    private byte timezonePart = 0;
-                    private boolean positive = true;
                     private String errorMessage = "This can not be an instance of date";
-                    private AMutableDate aDate = new AMutableDate(0, 0, 0, 0);
+                    private AMutableDate aDate = new AMutableDate(0);
                     @SuppressWarnings("unchecked")
                     private ISerializerDeserializer<ADate> dateSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ADATE);
@@ -60,6 +58,8 @@
                     private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ANULL);
 
+                    private GregorianCalendarSystem gCalInstance = GregorianCalendarSystem.getInstance();
+
                     @Override
                     public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
 
@@ -68,73 +68,229 @@
                             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;
 
-                                if (serString[offset] == '-') {
-                                    offset++;
-                                    positive = false;
-                                }
-
-                                if (serString[offset + 4] != '-' || serString[offset + 7] != '-')
-                                    throw new AlgebricksException(errorMessage);
-
-                                year = getValue(serString, offset, 4);
-                                month = getValue(serString, offset + 5, 2);
-                                day = getValue(serString, offset + 8, 2);
-
-                                if (year < 0 || year > 9999 || month < 0 || month > 12 || day < 0 || day > 31)
-                                    throw new AlgebricksException(errorMessage);
-
-                                offset += 10;
-
-                                if (outInput.getLength() > offset) {
-                                    if (serString[offset] == 'Z')
-                                        timezonePart = 0;
-                                    else {
-                                        if ((serString[offset] != '+' && serString[offset] != '-')
-                                                || (serString[offset + 3] != ':'))
-                                            throw new AlgebricksException(errorMessage);
-
-                                        hour = getValue(serString, offset + 1, 2);
-                                        minute = getValue(serString, offset + 4, 2);
-
-                                        if (hour < 0 || hour > 24 || (hour == 24 && minute != 0)
-                                                || (minute != 0 && minute != 15 && minute != 30 && minute != 45))
-                                            throw new AlgebricksException(errorMessage);
-
-                                        if (serString[offset] == '-')
-                                            timezonePart = (byte) -((hour * 4) + minute / 15);
-                                        else
-                                            timezonePart = (byte) ((hour * 4) + minute / 15);
+                                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);
+                                        }
+                                    }
                                 }
 
-                                if (!positive)
-                                    year *= -1;
+                                long chrononTimeInMs = gCalInstance.getChronon(year, month, day, 0, 0, 0, 0, timezone);
+                                aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY));
+                                if (chrononTimeInMs < 0
+                                        && chrononTimeInMs % GregorianCalendarSystem.CHRONON_OF_DAY != 0)
+                                    aDate.setValue((int) (chrononTimeInMs / GregorianCalendarSystem.CHRONON_OF_DAY) - 1);
 
-                                aDate.setValue(year, month, day, timezonePart);
                                 dateSerde.serialize(aDate, 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);
                         }
                     }
-
-                    private short getValue(byte[] b, int offset, int numberOfDigits) throws AlgebricksException {
-                        value = 0;
-                        for (int i = 0; i < numberOfDigits; i++) {
-                            if ((b[offset] >= '0' && b[offset] <= '9'))
-                                value = (short) (value * 10 + b[offset++] - '0');
-                            else
-                                throw new AlgebricksException(errorMessage);
-
-                        }
-                        return value;
-                    }
                 };
             }
         };
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 56c9dcf..2c711a5 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,6 +8,7 @@
 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.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -49,11 +50,8 @@
                     private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval = args[0].createEvaluator(outInput);
                     private int offset;
-                    private short hour, minute, second, msecond, year, month, day, timezoneHour, timezoneMinute, value;
-                    private byte timezonePart = 0;
-                    private boolean positive = true;
                     private String errorMessage = "This can not be an instance of datetime";
-                    private AMutableDateTime aDateTime = new AMutableDateTime(0, 0, 0, 0, 0, 0, 0, 0, 0);
+                    private AMutableDateTime aDateTime = new AMutableDateTime(0L);
                     @SuppressWarnings("unchecked")
                     private ISerializerDeserializer<ADateTime> datetimeSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ADATETIME);
@@ -61,6 +59,8 @@
                     private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ANULL);
 
+                    private GregorianCalendarSystem gCalInstance = GregorianCalendarSystem.getInstance();
+
                     @Override
                     public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
 
@@ -69,79 +69,379 @@
                             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;
-                                if (serString[offset] == '-') {
-                                    offset++;
-                                    positive = false;
+
+                                int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0, millis = 0;
+                                int timezone = 0;
+
+                                boolean positive = true;
+                                boolean isExtendedForm = false;
+                                if (serString[offset + 13] == ':' || serString[offset + 14] == ':') {
+                                    isExtendedForm = true;
                                 }
-
-                                if (serString[offset + 4] != '-' || serString[offset + 7] != '-')
-                                    throw new AlgebricksException(errorMessage);
-
-                                year = getValue(serString, offset, 4);
-                                month = getValue(serString, offset + 5, 2);
-                                day = getValue(serString, offset + 8, 2);
-
-                                if (year < 0 || year > 9999 || month < 0 || month > 12 || day < 0 || day > 31)
-                                    throw new AlgebricksException(errorMessage);
-
-                                if (!positive)
-                                    year *= -1;
-
-                                if (serString[offset + 10] != 'T')
-                                    throw new AlgebricksException(errorMessage);
-
-                                offset += 11;
-
-                                if (serString[offset + 2] != ':' || serString[offset + 5] != ':')
-                                    throw new AlgebricksException(errorMessage);
-
-                                hour = getValue(serString, offset, 2);
-                                minute = getValue(serString, offset + 3, 2);
-                                second = getValue(serString, offset + 6, 2);
-
-                                msecond = 0;
-                                if (serString[offset + 8] == ':') {
-                                    msecond = getValue(serString, offset + 9, 3);
-                                    if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
-                                            || msecond < 0 || msecond > 999
-                                            || (hour == 24 && (minute != 0 || second != 0 || msecond != 0)))
-                                        throw new AlgebricksException(errorMessage);
-                                    offset += 12;
-                                } else {
-                                    if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
-                                            || (hour == 24 && (minute != 0 || second != 0)))
-                                        throw new AlgebricksException(errorMessage);
-                                    offset += 8;
-                                }
-
-                                if (outInput.getLength() > offset) {
-                                    if (serString[offset] == 'Z')
-                                        timezonePart = 0;
-                                    else {
-                                        if ((serString[offset] != '+' && serString[offset] != '-')
-                                                || (serString[offset + 3] != ':'))
-                                            throw new AlgebricksException(errorMessage);
-
-                                        timezoneHour = getValue(serString, offset + 1, 2);
-                                        timezoneMinute = getValue(serString, offset + 4, 2);
-
-                                        if (timezoneHour < 0
-                                                || timezoneHour > 24
-                                                || (timezoneHour == 24 && timezoneMinute != 0)
-                                                || (timezoneMinute != 0 && timezoneMinute != 15 && timezoneMinute != 30 && timezoneMinute != 45))
-                                            throw new AlgebricksException(errorMessage);
-
-                                        if (serString[offset] == '-')
-                                            timezonePart = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
-                                        else
-                                            timezonePart = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+                                if (isExtendedForm) {
+                                    // 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;
+
+                                    // 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(year, month, day, hour, minute, second, msecond, 0, timezonePart);
+                                aDateTime.setValue(gCalInstance.getChronon(year, month, day, hour, min, sec,
+                                        (int) millis, timezone));
+
                                 datetimeSerde.serialize(aDateTime, out);
                             } else if (serString[0] == SER_NULL_TYPE_TAG)
                                 nullSerde.serialize(ANull.NULL, out);
@@ -151,18 +451,6 @@
                             throw new AlgebricksException(errorMessage);
                         }
                     }
-
-                    private short getValue(byte[] b, int offset, int numberOfDigits) throws AlgebricksException {
-                        value = 0;
-                        for (int i = 0; i < numberOfDigits; i++) {
-                            if ((b[offset] >= '0' && b[offset] <= '9'))
-                                value = (short) (value * 10 + b[offset++] - '0');
-                            else
-                                throw new AlgebricksException(errorMessage);
-
-                        }
-                        return value;
-                    }
                 };
             }
         };
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 feb2fd7..58a26ba 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
@@ -49,9 +49,10 @@
                     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, year = 0, month = 0, day = 0;
+                    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, isTime = false, timeItem = true, positive = 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")
@@ -74,7 +75,7 @@
                                     offset++;
                                     positive = false;
                                 }
-                                if (serString[offset++] != 'D')
+                                if (serString[offset++] != 'P')
                                     throw new AlgebricksException(errorMessage);
 
                                 for (; offset < outInput.getLength(); offset++) {
@@ -92,33 +93,21 @@
                                             case 'M':
                                                 if (!isTime) {
                                                     if (isMonth) {
-                                                        if (value < 0 || value > 11)
-                                                            throw new AlgebricksException(errorMessage);
-                                                        else {
-                                                            month = value;
-                                                            isMonth = false;
-                                                        }
+                                                        month = value;
+                                                        isMonth = false;
                                                     } else
                                                         throw new AlgebricksException(errorMessage);
                                                 } else if (isMinute) {
-                                                    if (value < 0 || value > 59)
-                                                        throw new AlgebricksException(errorMessage);
-                                                    else {
-                                                        minute = value;
-                                                        isMinute = false;
-                                                        timeItem = false;
-                                                    }
+                                                    minute = value;
+                                                    isMinute = false;
+                                                    timeItem = false;
                                                 } else
                                                     throw new AlgebricksException(errorMessage);
                                                 break;
                                             case 'D':
                                                 if (isDay) {
-                                                    if (value < 0 || value > 30)
-                                                        throw new AlgebricksException(errorMessage);
-                                                    else {
-                                                        day = value;
-                                                        isDay = false;
-                                                    }
+                                                    day = value;
+                                                    isDay = false;
                                                 } else
                                                     throw new AlgebricksException(errorMessage);
                                                 break;
@@ -132,25 +121,34 @@
 
                                             case 'H':
                                                 if (isHour) {
-                                                    if (value < 0 || value > 23)
-                                                        throw new AlgebricksException(errorMessage);
-                                                    else {
-                                                        hour = value;
-                                                        isHour = false;
-                                                        timeItem = false;
-                                                    }
+                                                    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) {
-                                                    if (value < 0 || value > 59)
-                                                        throw new AlgebricksException(errorMessage);
-                                                    else {
-                                                        second = value;
-                                                        isSecond = false;
-                                                        timeItem = false;
-                                                    }
+                                                    second = value;
+                                                    isSecond = false;
+                                                    timeItem = false;
                                                 } else
                                                     throw new AlgebricksException(errorMessage);
                                                 break;
@@ -165,15 +163,16 @@
                                 if (isTime && timeItem)
                                     throw new AlgebricksException(errorMessage);
 
-                                if (isYear && isMonth && isDay && !isTime)
-                                    throw new AlgebricksException(errorMessage);
+                                //                                if (isYear && isMonth && isDay && !isTime)
+                                //                                    throw new AlgebricksException(errorMessage);
 
                                 if (positive)
-                                    aDuration.setValue(year * 12 + month, day * 24 * 3600 + 3600 * hour + 60 * minute
-                                            + second);
+                                    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 + 3600 * hour + 60 * minute + second));
+                                            * (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);
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 c262d9f..a173ba7 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,6 +8,7 @@
 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.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -49,10 +50,8 @@
                     private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval = args[0].createEvaluator(outInput);
                     private int offset;
-                    private short hour, minute, second, msecond, timezoneHour, timezoneMinute, value;
-                    private byte timezonePart = 0;
                     private String errorMessage = "This can not be an instance of time";
-                    private AMutableTime aTime = new AMutableTime(0, 0, 0, 0, 0, 0);
+                    private AMutableTime aTime = new AMutableTime(0);
                     @SuppressWarnings("unchecked")
                     private ISerializerDeserializer<ATime> timeSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ATIME);
@@ -68,54 +67,242 @@
                             eval.evaluate(tuple);
                             byte[] serString = outInput.getByteArray();
                             if (serString[0] == SER_STRING_TYPE_TAG) {
+
                                 offset = 3;
-                                if (serString[offset + 2] != ':' || serString[offset + 5] != ':')
-                                    throw new AlgebricksException(errorMessage);
 
-                                hour = getValue(serString, offset, 2);
-                                minute = getValue(serString, offset + 3, 2);
-                                second = getValue(serString, offset + 6, 2);
-                                msecond = 0;
+                                int length = ((serString[1] & 0xff) << 8) + ((serString[2] & 0xff) << 0) + 3;
 
-                                if (serString[offset + 8] == ':') {
-                                    msecond = getValue(serString, offset + 9, 3);
-                                    if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
-                                            || msecond < 0 || msecond > 999
-                                            || (hour == 24 && (minute != 0 || second != 0 || msecond != 0)))
-                                        throw new AlgebricksException(errorMessage);
-                                    offset += 12;
-                                } else {
-                                    if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
-                                            || (hour == 24 && (minute != 0 || second != 0)))
-                                        throw new AlgebricksException(errorMessage);
-                                    offset += 8;
+                                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);
 
-                                if (outInput.getLength() > offset) {
-                                    if (serString[offset] == 'Z')
-                                        timezonePart = 0;
-                                    else {
-                                        if ((serString[offset] != '+' && serString[offset] != '-')
-                                                || (serString[offset + 3] != ':'))
-                                            throw new AlgebricksException(errorMessage);
-
-                                        timezoneHour = getValue(serString, offset + 1, 2);
-                                        timezoneMinute = getValue(serString, offset + 4, 2);
-
-                                        if (timezoneHour < 0
-                                                || timezoneHour > 24
-                                                || (timezoneHour == 24 && timezoneMinute != 0)
-                                                || (timezoneMinute != 0 && timezoneMinute != 15 && timezoneMinute != 30 && timezoneMinute != 45))
-                                            throw new AlgebricksException(errorMessage);
-
-                                        if (serString[offset] == '-')
-                                            timezonePart = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
+                                    for (int i = 0; i < 2; i++) {
+                                        if ((serString[offset + i] >= '0' && serString[offset + i] <= '9'))
+                                            hour = hour * 10 + serString[offset + i] - '0';
                                         else
-                                            timezonePart = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+                                            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(hour, minute, second, msecond, 0, timezonePart);
+                                aTime.setValue(GregorianCalendarSystem.getInstance().getChronon(hour, min, sec, millis,
+                                        timezone));
+
                                 timeSerde.serialize(aTime, out);
 
                             } else if (serString[0] == SER_NULL_TYPE_TAG)
@@ -126,17 +313,6 @@
                             throw new AlgebricksException(errorMessage);
                         }
                     }
-
-                    private short getValue(byte[] b, int offset, int numberOfDigits) throws AlgebricksException {
-                        value = 0;
-                        for (int i = 0; i < numberOfDigits; i++) {
-                            if ((b[offset] >= '0' && b[offset] <= '9'))
-                                value = (short) (value * 10 + b[offset++] - '0');
-                            else
-                                throw new AlgebricksException(errorMessage);
-                        }
-                        return value;
-                    }
                 };
             }
         };