added interval-bin function with test cases for issue 546
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.1.ddl.aql
deleted file mode 100644
index 754ea81..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.1.ddl.aql
+++ /dev/null
@@ -1,3 +0,0 @@
-drop dataverse test if exists;
-create dataverse test;
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.2.update.aql
deleted file mode 100644
index e69de29..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.2.update.aql
+++ /dev/null
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.3.query.aql
deleted file mode 100644
index 169ca39..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.3.query.aql
+++ /dev/null
@@ -1,7 +0,0 @@
-use dataverse test;
-
-let $c1 := double("-20.56e-30")
-let $c2 := double("NaN")
-let $c3 := double("INF")
-let $c4 := double("-INF")
-return {"double1": numeric-unary-minus($c1),"double2": numeric-unary-minus($c2),"double3": numeric-unary-minus($c3),"double4": numeric-unary-minus($c4)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.1.ddl.aql
deleted file mode 100644
index 754ea81..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.1.ddl.aql
+++ /dev/null
@@ -1,3 +0,0 @@
-drop dataverse test if exists;
-create dataverse test;
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.2.update.aql
deleted file mode 100644
index e69de29..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.2.update.aql
+++ /dev/null
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.3.query.aql
deleted file mode 100644
index e5e0071..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.3.query.aql
+++ /dev/null
@@ -1,7 +0,0 @@
-use dataverse test;
-
-let $c1 := float("-80.20f")
-let $c2 := float("NaN")
-let $c3 := float("INF")
-let $c4 := float("-INF")
-return {"float1": numeric-unary-minus($c1),"float2": numeric-unary-minus($c2),"float3": numeric-unary-minus($c3),"float4": numeric-unary-minus($c4)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.1.ddl.aql
deleted file mode 100644
index 754ea81..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.1.ddl.aql
+++ /dev/null
@@ -1,3 +0,0 @@
-drop dataverse test if exists;
-create dataverse test;
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.2.update.aql
deleted file mode 100644
index e69de29..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.2.update.aql
+++ /dev/null
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.3.query.aql
deleted file mode 100644
index 660e55f..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.3.query.aql
+++ /dev/null
@@ -1,7 +0,0 @@
-use dataverse test;
-
-let $c1 := int8("+80")
-let $c2 := int16("160")
-let $c3 := int32("+320")
-let $c4 := int64("-640")
-return {"int8": numeric-unary-minus($c1),"int16": numeric-unary-minus($c2),"int32": numeric-unary-minus($c3),"int64": numeric-unary-minus($c4)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.1.ddl.aql
new file mode 100644
index 0000000..57b3b28
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.1.ddl.aql
@@ -0,0 +1,7 @@
+/**
+ * Interval_bin test case: test the interval-bin function
+ * Expected result: success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.2.update.aql
new file mode 100644
index 0000000..e2e3afb
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.2.update.aql
@@ -0,0 +1,4 @@
+/**
+ * Interval_bin test case: test the interval-bin function
+ * Expected result: success
+ **/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.3.query.aql
new file mode 100644
index 0000000..adbb2a2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.3.query.aql
@@ -0,0 +1,19 @@
+/**
+ * Interval_bin test case: test the interval-bin function
+ * Expected result: success
+ **/
+
+use dataverse test;
+
+let $c1 := date("2010-10-30")
+let $c2 := datetime("-1987-11-19T23:49:23.938")
+let $c3 := time("12:23:34.930+07:00")
+
+return { "bin1": interval-bin($c1, date("1990-01-01"), year-month-duration("P1Y")), 
+         "bin2": interval-bin($c1, date("-1990-01-01"), year-month-duration("P1Y")),
+         "bin3": interval-bin($c2, datetime("1990-01-01T00:00:00.000Z"), year-month-duration("P6M")),
+         "bin4": interval-bin($c2, datetime("-1990-01-01T00:00:00.000Z"), day-time-duration("PT12H")),
+         "bin5": interval-bin($c3, time("12:00:00"), day-time-duration("PT2H")),
+         "bin6": interval-bin(null, date("-0023-01-01"), year-month-duration("P6M")),
+         "bin7": interval-bin($c1, null, year-month-duration("P6M")),
+         "bin8": interval-bin($c1, date("-0023-01-01"), null)  }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.1.ddl.aql
new file mode 100644
index 0000000..841d8da
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.1.ddl.aql
@@ -0,0 +1,16 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type Schema as closed{
+id: int32,
+timestamp: datetime
+}
+
+create dataset tsdata(Schema)
+primary key id;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.2.update.aql
new file mode 100644
index 0000000..b1119e5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.2.update.aql
@@ -0,0 +1,18 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+use dataverse test;
+ 
+insert into dataset tsdata({"id": 1, "timestamp": datetime("-1987-11-19T23:49:23.938")}) 
+insert into dataset tsdata({"id": 2, "timestamp": datetime("-1987-11-20T00:27:13.432")}) 
+insert into dataset tsdata({"id": 3, "timestamp": datetime("-1987-11-18T18:00:00")}) 
+insert into dataset tsdata({"id": 4, "timestamp": datetime("19871119T234923938")}) 
+insert into dataset tsdata({"id": 5, "timestamp": datetime("1987-11-19T23:58:17.038")}) 
+insert into dataset tsdata({"id": 6, "timestamp": datetime("1987-11-19T23:30:00")}) 
+insert into dataset tsdata({"id": 7, "timestamp": datetime("1987-11-19T23:22:38")}) 
+insert into dataset tsdata({"id": 8, "timestamp": datetime("1988-01-21T17:28:13.900")}) 
+insert into dataset tsdata({"id": 9, "timestamp": datetime("-1987-11-19T23:49:23.938")}) 
+insert into dataset tsdata({"id": 10, "timestamp": datetime("-0987-07-01T09:35:28.039")}) 
+insert into dataset tsdata({"id": 11, "timestamp": datetime("2012-11-19T23:49:23.938")}) 
+insert into dataset tsdata({"id": 12, "timestamp": datetime("2013-11-19T23:49:23.938")}) 
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.3.query.aql
new file mode 100644
index 0000000..776493f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.3.query.aql
@@ -0,0 +1,11 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+
+use dataverse test;
+
+for $i in dataset tsdata
+group by $d := interval-bin($i.timestamp, datetime("1990-01-01T00:00:00.000Z"), year-month-duration("P20Y")) with $i 
+order by get-interval-start($d)
+return { "tbin": $d, "count": count($i)}
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.1.ddl.aql
new file mode 100644
index 0000000..841d8da
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.1.ddl.aql
@@ -0,0 +1,16 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type Schema as closed{
+id: int32,
+timestamp: datetime
+}
+
+create dataset tsdata(Schema)
+primary key id;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.2.update.aql
new file mode 100644
index 0000000..b1119e5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.2.update.aql
@@ -0,0 +1,18 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+use dataverse test;
+ 
+insert into dataset tsdata({"id": 1, "timestamp": datetime("-1987-11-19T23:49:23.938")}) 
+insert into dataset tsdata({"id": 2, "timestamp": datetime("-1987-11-20T00:27:13.432")}) 
+insert into dataset tsdata({"id": 3, "timestamp": datetime("-1987-11-18T18:00:00")}) 
+insert into dataset tsdata({"id": 4, "timestamp": datetime("19871119T234923938")}) 
+insert into dataset tsdata({"id": 5, "timestamp": datetime("1987-11-19T23:58:17.038")}) 
+insert into dataset tsdata({"id": 6, "timestamp": datetime("1987-11-19T23:30:00")}) 
+insert into dataset tsdata({"id": 7, "timestamp": datetime("1987-11-19T23:22:38")}) 
+insert into dataset tsdata({"id": 8, "timestamp": datetime("1988-01-21T17:28:13.900")}) 
+insert into dataset tsdata({"id": 9, "timestamp": datetime("-1987-11-19T23:49:23.938")}) 
+insert into dataset tsdata({"id": 10, "timestamp": datetime("-0987-07-01T09:35:28.039")}) 
+insert into dataset tsdata({"id": 11, "timestamp": datetime("2012-11-19T23:49:23.938")}) 
+insert into dataset tsdata({"id": 12, "timestamp": datetime("2013-11-19T23:49:23.938")}) 
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.3.query.aql
new file mode 100644
index 0000000..61a4c5b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.3.query.aql
@@ -0,0 +1,11 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+
+use dataverse test;
+
+for $i in dataset tsdata
+group by $d := interval-bin(get-time-from-datetime($i.timestamp), time("00:00:00.000Z"), day-time-duration("PT10M")) with $i 
+order by get-interval-start($d)
+return { "tbin": $d, "count": count($i)}
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_double_01/unary-minus_double_01.1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_double_01/unary-minus_double_01.1.adm
deleted file mode 100644
index 3a72bb8..0000000
--- a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_double_01/unary-minus_double_01.1.adm
+++ /dev/null
@@ -1 +0,0 @@
-{ "double1": 2.056E-29d, "double2": NaNd, "double3": -Infinityd, "double4": Infinityd }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_float_01/unary-minus_float_01.1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_float_01/unary-minus_float_01.1.adm
deleted file mode 100644
index e6541ae..0000000
--- a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_float_01/unary-minus_float_01.1.adm
+++ /dev/null
@@ -1 +0,0 @@
-{ "float1": 80.2f, "float2": NaNf, "float3": -Infinityf, "float4": Infinityf }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_int_01/unary-minus_int_01.1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_int_01/unary-minus_int_01.1.adm
deleted file mode 100644
index 4ecc59b..0000000
--- a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_int_01/unary-minus_int_01.1.adm
+++ /dev/null
@@ -1 +0,0 @@
-{ "int8": -80i8, "int16": -160i16, "int32": -320, "int64": 640i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin/interval_bin.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin/interval_bin.1.adm
new file mode 100644
index 0000000..3ba93a5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin/interval_bin.1.adm
@@ -0,0 +1 @@
+{ "bin1": interval-date("2010-01-01, 2011-01-01"), "bin2": interval-date("2010-01-01, 2011-01-01"), "bin3": interval-datetime("-1987-07-01T00:00:00.000Z, -1986-01-01T00:00:00.000Z"), "bin4": interval-datetime("-1987-11-19T12:00:00.000Z, -1987-11-20T00:00:00.000Z"), "bin5": interval-time("04:00:00.000Z, 06:00:00.000Z"), "bin6": null, "bin7": null, "bin8": null }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_0/interval_bin_gby_0.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_0/interval_bin_gby_0.1.adm
new file mode 100644
index 0000000..c21626b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_0/interval_bin_gby_0.1.adm
@@ -0,0 +1,4 @@
+{ "tbin": interval-datetime("-1990-01-01T00:00:00.000Z, -1970-01-01T00:00:00.000Z"), "count": 4i64 }
+{ "tbin": interval-datetime("-0990-01-01T00:00:00.000Z, -0970-01-01T00:00:00.000Z"), "count": 1i64 }
+{ "tbin": interval-datetime("1970-01-01T00:00:00.000Z, 1990-01-01T00:00:00.000Z"), "count": 5i64 }
+{ "tbin": interval-datetime("2010-01-01T00:00:00.000Z, 2030-01-01T00:00:00.000Z"), "count": 2i64 }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_1/interval_bin_gby_1.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_1/interval_bin_gby_1.1.adm
new file mode 100644
index 0000000..b67989d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_1/interval_bin_gby_1.1.adm
@@ -0,0 +1,8 @@
+{ "tbin": interval-time("00:20:00.000Z, 00:30:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("09:30:00.000Z, 09:40:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("17:20:00.000Z, 17:30:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("18:00:00.000Z, 18:10:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("23:20:00.000Z, 23:30:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("23:30:00.000Z, 23:40:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("23:40:00.000Z, 23:50:00.000Z"), "count": 5i64 }
+{ "tbin": interval-time("23:50:00.000Z, 00:00:00.000Z"), "count": 1i64 }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 65ef11f..95c002e 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -4322,6 +4322,21 @@
     </test-case>
   </test-group>
   <test-group name="temporal">
+  <test-case FilePath="temporal">
+     <compilation-unit name="interval_bin">
+        <output-dir compare="Text">interval_bin</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="temporal">
+     <compilation-unit name="interval_bin_gby_0">
+        <output-dir compare="Text">interval_bin_gby_0</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="temporal">
+     <compilation-unit name="interval_bin_gby_1">
+        <output-dir compare="Text">interval_bin_gby_1</output-dir>
+      </compilation-unit>
+    </test-case>
     <test-case FilePath="temporal">
   	  <compilation-unit name="accessors">
         <output-dir compare="Text">accessors</output-dir>
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
index f81de92..ab975fd 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -194,8 +194,7 @@
             "numeric-idiv", 2);
     public final static FunctionIdentifier CARET = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "caret", 2);
 
-    public final static FunctionIdentifier NUMERIC_ABS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
-            "abs", 1);
+    public final static FunctionIdentifier NUMERIC_ABS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "abs", 1);
     public final static FunctionIdentifier NUMERIC_CEILING = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "ceiling", 1);
     public final static FunctionIdentifier NUMERIC_FLOOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -424,7 +423,8 @@
             "interval-overlaps", 2);
     public final static FunctionIdentifier INTERVAL_OVERLAPPED_BY = new FunctionIdentifier(
             FunctionConstants.ASTERIX_NS, "interval-overlapped-by", 2);
-    public final static FunctionIdentifier OVERLAP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "interval-overlapping", 2);
+    public final static FunctionIdentifier OVERLAP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "interval-overlapping", 2);
     public final static FunctionIdentifier INTERVAL_STARTS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "interval-starts", 2);
     public final static FunctionIdentifier INTERVAL_STARTED_BY = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -518,6 +518,8 @@
             FunctionConstants.ASTERIX_NS, "get-interval-start", 1);
     public static final FunctionIdentifier ACCESSOR_TEMPORAL_INTERVAL_END = new FunctionIdentifier(
             FunctionConstants.ASTERIX_NS, "get-interval-end", 1);
+    public static final FunctionIdentifier INTERVAL_BIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "interval-bin", 3);
 
     // Temporal functions
     public static final FunctionIdentifier DATE_FROM_UNIX_TIME_IN_DAYS = new FunctionIdentifier(
@@ -855,6 +857,7 @@
         addFunction(MILLISECONDS_FROM_DAY_TIME_DURATION, OptionalAInt64TypeComputer.INSTANCE);
         addFunction(GET_DAY_TIME_DURATION, OptionalADayTimeDurationTypeComputer.INSTANCE);
         addFunction(GET_YEAR_MONTH_DURATION, OptionalAYearMonthDurationTypeComputer.INSTANCE);
+        addFunction(INTERVAL_BIN, OptionalAIntervalTypeComputer.INSTANCE);
 
         // interval constructors
         addFunction(INTERVAL_CONSTRUCTOR_DATE, OptionalAIntervalTypeComputer.INSTANCE);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/IntervalBinDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/IntervalBinDescriptor.java
new file mode 100644
index 0000000..28ce0db
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/IntervalBinDescriptor.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.runtime.evaluators.functions.temporal;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADayTimeDurationSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AYearMonthDurationSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInterval;
+import edu.uci.ics.asterix.om.base.AMutableInterval;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.DurationArithmeticOperations;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
+import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class IntervalBinDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new IntervalBinDescriptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+        return new ICopyEvaluatorFactory() {
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+
+                    private final DataOutput out = output.getDataOutput();
+
+                    private final ArrayBackedValueStorage argOut0 = new ArrayBackedValueStorage();
+                    private final ArrayBackedValueStorage argOut1 = new ArrayBackedValueStorage();
+                    private final ArrayBackedValueStorage argOut2 = new ArrayBackedValueStorage();
+
+                    private final ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
+                    private final ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
+                    private final ICopyEvaluator eval2 = args[2].createEvaluator(argOut2);
+
+                    private final AMutableInterval aInterval = new AMutableInterval(0, 0, (byte) -1);
+
+                    @SuppressWarnings("unchecked")
+                    private final ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ANULL);
+                    @SuppressWarnings("unchecked")
+                    private final ISerializerDeserializer<AInterval> intervalSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.AINTERVAL);
+
+                    private final GregorianCalendarSystem GREG_CAL = GregorianCalendarSystem.getInstance();
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        argOut0.reset();
+                        eval0.evaluate(tuple);
+
+                        ATypeTag type0 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]);
+
+                        long chrononToBin = 0;
+                        switch (type0) {
+                            case DATE:
+                                chrononToBin = ADateSerializerDeserializer.getChronon(argOut0.getByteArray(), 1)
+                                        * GregorianCalendarSystem.CHRONON_OF_DAY;
+                                break;
+                            case TIME:
+                                chrononToBin = ATimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+                                break;
+                            case DATETIME:
+                                chrononToBin = ADateTimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+                                break;
+                            case NULL:
+                                try {
+                                    nullSerde.serialize(ANull.NULL, out);
+                                } catch (HyracksDataException e) {
+                                    throw new AlgebricksException(e);
+                                }
+                                return;
+                            default:
+                                throw new AlgebricksException(getIdentifier().getName()
+                                        + ": the first argument should be DATE/TIME/DATETIME/NULL but got " + type0);
+
+                        }
+
+                        argOut1.reset();
+                        eval1.evaluate(tuple);
+
+                        ATypeTag type1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]);
+
+                        long chrononToStart = 0;
+                        switch (type1) {
+                            case DATE:
+                                chrononToStart = ADateSerializerDeserializer.getChronon(argOut1.getByteArray(), 1)
+                                        * GregorianCalendarSystem.CHRONON_OF_DAY;
+                                break;
+                            case TIME:
+                                chrononToStart = ATimeSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+                                break;
+                            case DATETIME:
+                                chrononToStart = ADateTimeSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+                                break;
+                            case NULL:
+                                try {
+                                    nullSerde.serialize(ANull.NULL, out);
+                                } catch (HyracksDataException e) {
+                                    throw new AlgebricksException(e);
+                                }
+                                return;
+                            default:
+                                throw new AlgebricksException(getIdentifier().getName() + ": expecting " + type0
+                                        + " for the second argument but got " + type1);
+                        }
+
+                        argOut2.reset();
+                        eval2.evaluate(tuple);
+
+                        ATypeTag type2 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut2.getByteArray()[0]);
+
+                        int yearMonth = 0;
+                        long dayTime = 0;
+                        long binIndex, binStartChronon, binEndChronon;
+                        switch (type2) {
+                            case YEARMONTHDURATION:
+
+                                yearMonth = AYearMonthDurationSerializerDeserializer.getYearMonth(
+                                        argOut2.getByteArray(), 1);
+
+                                int yearStart = GREG_CAL.getYear(chrononToStart);
+                                int monthStart = GREG_CAL.getMonthOfYear(chrononToStart, yearStart);
+                                int yearToBin = GREG_CAL.getYear(chrononToBin);
+                                int monthToBin = GREG_CAL.getMonthOfYear(chrononToBin, yearToBin);
+
+                                int totalMonths = (yearToBin - yearStart) * 12 + (monthToBin - monthStart);
+
+                                binIndex = totalMonths / yearMonth
+                                        + ((totalMonths < 0 && totalMonths % yearMonth != 0) ? -1 : 0);
+
+                                if (binIndex > Integer.MAX_VALUE) {
+                                    throw new AlgebricksException(getIdentifier().getName()
+                                            + ": Overflowing time value to be binned!");
+                                }
+
+                                if (binIndex < Integer.MIN_VALUE) {
+                                    throw new AlgebricksException(getIdentifier().getName()
+                                            + ": Underflowing time value to be binned!");
+                                }
+
+                                break;
+
+                            case DAYTIMEDURATION:
+                                dayTime = ADayTimeDurationSerializerDeserializer.getDayTime(argOut2.getByteArray(), 1);
+
+                                long totalChronon = chrononToBin - chrononToStart;
+
+                                binIndex = totalChronon / dayTime
+                                        + ((totalChronon < 0 && totalChronon % dayTime != 0) ? -1 : 0);
+
+                                break;
+                            case NULL:
+                                try {
+                                    nullSerde.serialize(ANull.NULL, out);
+                                } catch (HyracksDataException e) {
+                                    throw new AlgebricksException(e);
+                                }
+                                return;
+                            default:
+                                throw new AlgebricksException(
+                                        getIdentifier().getName()
+                                                + ": expecting YEARMONTHDURATION/DAYTIMEDURATION for the thrid argument but got "
+                                                + type2);
+                        }
+
+                        switch (type0) {
+                            case DATE:
+                                binStartChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+                                        * (int) binIndex, dayTime * binIndex, false);
+                                binEndChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+                                        * ((int) binIndex + 1), dayTime * (binIndex + 1), false);
+
+                                binStartChronon = binStartChronon
+                                        / GregorianCalendarSystem.CHRONON_OF_DAY
+                                        + ((binStartChronon < 0 && binStartChronon
+                                                % GregorianCalendarSystem.CHRONON_OF_DAY != 0) ? -1 : 0);
+                                binEndChronon = binEndChronon
+                                        / GregorianCalendarSystem.CHRONON_OF_DAY
+                                        + ((binEndChronon < 0 && binEndChronon % GregorianCalendarSystem.CHRONON_OF_DAY != 0) ? -1
+                                                : 0);
+                                break;
+                            case TIME:
+                                if (yearMonth != 0) {
+                                    throw new AlgebricksException(getIdentifier().getName()
+                                            + ": cannot create year-month bin for a time value");
+                                }
+                                binStartChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+                                        * (int) binIndex, dayTime * binIndex, true);
+                                binEndChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+                                        * ((int) binIndex + 1), dayTime * (binIndex + 1), true);
+                                break;
+                            case DATETIME:
+                                binStartChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+                                        * (int) binIndex, dayTime * binIndex, false);
+                                binEndChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+                                        * ((int) binIndex + 1), dayTime * (binIndex + 1), false);
+                                break;
+                            case NULL:
+                                try {
+                                    nullSerde.serialize(ANull.NULL, out);
+                                } catch (HyracksDataException e) {
+                                    throw new AlgebricksException(e);
+                                }
+                                return;
+                            default:
+                                throw new AlgebricksException(getIdentifier().getName() + ": expecting " + type0
+                                        + " for the second argument but got " + type1);
+
+                        }
+                        aInterval.setValue(binStartChronon, binEndChronon, type0.serialize());
+                        try {
+                            intervalSerde.serialize(aInterval, out);
+                            return;
+                        } catch (HyracksDataException ex) {
+                            throw new AlgebricksException(ex);
+                        }
+
+                    }
+                };
+            }
+
+        };
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
+     */
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.INTERVAL_BIN;
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
index 5646aa2..47555bd 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -230,6 +230,7 @@
 import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.GetYearMonthDurationDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalAfterDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalBeforeDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalBinDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalCoveredByDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalCoversDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalEndedByDescriptor;
@@ -537,6 +538,7 @@
         temp.add(DurationEqualDescriptor.FACTORY);
         temp.add(GetYearMonthDurationDescriptor.FACTORY);
         temp.add(GetDayTimeDurationDescriptor.FACTORY);
+        temp.add(IntervalBinDescriptor.FACTORY);
 
         // Interval constructor
         temp.add(AIntervalFromDateConstructorDescriptor.FACTORY);
@@ -939,9 +941,9 @@
         return AqlBinaryHashFunctionFamilyProvider.INSTANCE;
     }
 
-	@Override
-	public IPredicateEvaluatorFactoryProvider getPredicateEvaluatorFactoryProvider() {
-		return AqlPredicateEvaluatorFactoryProvider.INSTANCE;
-	}
+    @Override
+    public IPredicateEvaluatorFactoryProvider getPredicateEvaluatorFactoryProvider() {
+        return AqlPredicateEvaluatorFactoryProvider.INSTANCE;
+    }
 
 }