PHOENIX-688 Add to_time and to_timestamp built-in functions

Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/11a76b29
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/11a76b29
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/11a76b29

Branch: refs/heads/calcite
Commit: 11a76b297fad46cd7f51019810ba4d1a7b51b418
Parents: 78d91d1
Author: James Taylor <jtay...@salesforce.com>
Authored: Sat Feb 7 23:54:53 2015 -0800
Committer: James Taylor <jtay...@salesforce.com>
Committed: Mon Feb 9 18:37:14 2015 -0800

----------------------------------------------------------------------
 .../phoenix/end2end/ProductMetricsIT.java       |   4 +-
 .../phoenix/end2end/ToDateFunctionIT.java       |  67 +++++-
 .../phoenix/end2end/TruncateFunctionIT.java     |   5 +-
 .../apache/phoenix/end2end/UpsertValuesIT.java  |   6 +-
 .../phoenix/end2end/VariableLengthPKIT.java     |   3 +-
 .../phoenix/mapreduce/CsvBulkLoadToolIT.java    |  10 +-
 .../phoenix/compile/StatementContext.java       |  28 ++-
 .../phoenix/expression/ExpressionType.java      |  10 +-
 .../expression/function/ToDateFunction.java     |  93 ++++++--
 .../expression/function/ToTimeFunction.java     |  63 ++++++
 .../function/ToTimestampFunction.java           |  63 ++++++
 .../apache/phoenix/jdbc/PhoenixConnection.java  |  20 +-
 .../apache/phoenix/parse/ToDateParseNode.java   |   6 +-
 .../apache/phoenix/parse/ToTimeParseNode.java   |  48 +++++
 .../phoenix/parse/ToTimestampParseNode.java     |  48 +++++
 .../org/apache/phoenix/query/QueryServices.java |   3 +
 .../org/apache/phoenix/schema/types/PDate.java  |  12 +-
 .../org/apache/phoenix/schema/types/PTime.java  |  16 +-
 .../apache/phoenix/schema/types/PTimestamp.java |  24 +--
 .../java/org/apache/phoenix/util/DateUtil.java  | 213 +++++++++++++------
 .../phoenix/util/csv/CsvUpsertExecutor.java     |  52 +++--
 .../phoenix/compile/WhereCompilerTest.java      |   8 +-
 .../expression/SortOrderExpressionTest.java     |  34 +--
 .../org/apache/phoenix/util/DateUtilTest.java   |  35 +--
 24 files changed, 656 insertions(+), 215 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java
index 975541e..ddc5fab 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java
@@ -31,8 +31,6 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
-import java.text.Format;
-import java.text.ParseException;
 import java.util.Collections;
 import java.util.List;
 import java.util.Properties;
@@ -87,7 +85,7 @@ public class ProductMetricsIT extends BaseClientManagedTimeIT 
{
     }
     
     private static Date toDate(String dateString) {
-        return DateUtil.parseDateTime(dateString);
+        return DateUtil.parseDate(dateString);
     }
     
     private static void initTable(byte[][] splits, long ts) throws Exception {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java
index 984e21b..bda4ea5 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java
@@ -18,24 +18,25 @@
 
 package org.apache.phoenix.end2end;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.sql.Connection;
 import java.sql.Date;
 import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
 import java.util.Properties;
 
 import org.apache.phoenix.query.QueryServices;
-import org.apache.phoenix.util.DateUtil;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 
 public class ToDateFunctionIT extends BaseHBaseManagedTimeIT {
 
@@ -53,18 +54,26 @@ public class ToDateFunctionIT extends 
BaseHBaseManagedTimeIT {
         conn.close();
     }
 
-    private static Date callToDateFunction(Connection conn, String invocation) 
throws SQLException {
+    private static java.util.Date callToDateFunction(Connection conn, String 
invocation) throws SQLException {
         Statement stmt = conn.createStatement();
-        ResultSet rs = stmt.executeQuery(String.format("SELECT %s FROM 
SYSTEM.CATALOG", invocation));
+        ResultSet rs = stmt.executeQuery(String.format("SELECT %s FROM 
SYSTEM.CATALOG LIMIT 1", invocation));
         assertTrue(rs.next());
-        Date returnValue = rs.getDate(1);
+        java.util.Date returnValue = (java.util.Date)rs.getObject(1);
         rs.close();
         stmt.close();
         return returnValue;
     }
 
     private Date callToDateFunction(String invocation) throws SQLException {
-        return callToDateFunction(conn, invocation);
+        return (Date)callToDateFunction(conn, invocation);
+    }
+
+    private Time callToTimeFunction(String invocation) throws SQLException {
+        return (Time)callToDateFunction(conn, invocation);
+    }
+
+    private Timestamp callToTimestampFunction(String invocation) throws 
SQLException {
+        return (Timestamp)callToDateFunction(conn, invocation);
     }
 
     @Test
@@ -87,6 +96,44 @@ public class ToDateFunctionIT extends BaseHBaseManagedTimeIT 
{
     }
 
     @Test
+    public void testToTime_Default() throws SQLException {
+        // Default time zone is GMT, so this is timestamp 0
+        assertEquals(0L, callToTimeFunction("TO_TIME('1970-01-01 
00:00:00')").getTime());
+        assertEquals(0L, callToTimeFunction("TO_TIME('1970-01-01 
00:00:00.000')").getTime());
+        assertEquals(0L, 
callToTimeFunction("TO_TIME('1970-01-01')").getTime());
+        assertEquals(0L, 
callToTimeFunction("TO_TIME('1970/01/01','yyyy/MM/dd')").getTime());
+
+        // Test other ISO 8601 Date Compliant Formats to verify they can be 
parsed
+        try {
+            callToTimeFunction("TO_TIME('2015-01-27T16:17:57+00:00')");
+            callToTimeFunction("TO_TIME('2015-01-27T16:17:57Z')");
+            callToTimeFunction("TO_TIME('2015-W05')");
+            callToTimeFunction("TO_TIME('2015-W05-2')");
+        } catch (Exception ex) {
+            fail("TO_TIME Parse ISO8601 Time Failed due to:" + ex);
+        }
+    }
+
+    @Test
+    public void testToTimestamp_Default() throws SQLException {
+        // Default time zone is GMT, so this is timestamp 0
+        assertEquals(0L, callToTimestampFunction("TO_TIMESTAMP('1970-01-01 
00:00:00')").getTime());
+        assertEquals(0L, callToTimestampFunction("TO_TIMESTAMP('1970-01-01 
00:00:00.000')").getTime());
+        assertEquals(0L, 
callToTimestampFunction("TO_TIMESTAMP('1970-01-01')").getTime());
+        assertEquals(0L, 
callToTimestampFunction("TO_TIMESTAMP('1970/01/01','yyyy/MM/dd')").getTime());
+
+        // Test other ISO 8601 Date Compliant Formats to verify they can be 
parsed
+        try {
+            
callToTimestampFunction("TO_TIMESTAMP('2015-01-27T16:17:57+00:00')");
+            callToTimestampFunction("TO_TIMESTAMP('2015-01-27T16:17:57Z')");
+            callToTimestampFunction("TO_TIMESTAMP('2015-W05')");
+            callToTimestampFunction("TO_TIMESTAMP('2015-W05-2')");
+        } catch (Exception ex) {
+            fail("TO_TIMESTAMP Parse ISO8601 Time Failed due to:" + ex);
+        }
+    }
+
+    @Test
     public void testToDate_CustomDateFormat() throws SQLException {
         // A date without time component is at midnight
         assertEquals(0L, callToDateFunction("TO_DATE('1970-01-01', 
'yyyy-MM-dd')").getTime());
@@ -115,7 +162,7 @@ public class ToDateFunctionIT extends 
BaseHBaseManagedTimeIT {
 
         assertEquals(
                 -ONE_HOUR_IN_MILLIS,
-                callToDateFunction(customTimeZoneConn, "TO_DATE('1970-01-01 
00:00:00')").getTime());
+                callToDateFunction(customTimeZoneConn, "TO_DATE('1970-01-01 
00:00:00.000')").getTime());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/it/java/org/apache/phoenix/end2end/TruncateFunctionIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TruncateFunctionIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TruncateFunctionIT.java
index 59c499d..9e8f2c0 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TruncateFunctionIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TruncateFunctionIT.java
@@ -32,7 +32,6 @@ import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.Timestamp;
-import java.text.Format;
 import java.text.ParseException;
 import java.util.Properties;
 
@@ -47,11 +46,11 @@ public class TruncateFunctionIT extends 
BaseClientManagedTimeIT {
     private static final String DS3 = "1970-01-30 01:30:24.353";
     
     private static Date toDate(String s) throws ParseException {
-        return DateUtil.parseDateTime(s);
+        return DateUtil.parseDate(s);
     }
     
     private static Timestamp toTimestamp(String s) throws ParseException {
-        return new Timestamp((DateUtil.parseDateTime(s)).getTime());
+        return DateUtil.parseTimestamp(s);
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
index b44fbff..8e07af5 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
@@ -33,8 +33,8 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
-import java.sql.Timestamp;
 import java.sql.Time;
+import java.sql.Timestamp;
 import java.util.Properties;
 
 import org.apache.phoenix.exception.SQLExceptionCode;
@@ -156,7 +156,7 @@ public class UpsertValuesIT extends BaseClientManagedTimeIT 
{
         ResultSet rs = conn.createStatement().executeQuery("select 
k,to_char(date) from UpsertDateTest");
         assertTrue(rs.next());
         assertEquals("a", rs.getString(1));
-        assertEquals("2013-06-08 00:00:00", rs.getString(2));
+        assertEquals("2013-06-08 00:00:00.000", rs.getString(2));
     }
 
     @Test
@@ -548,7 +548,7 @@ public class UpsertValuesIT extends BaseClientManagedTimeIT 
{
     }
     
     private static Date toDate(String dateString) {
-        return DateUtil.parseDateTime(dateString);
+        return DateUtil.parseDate(dateString);
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
index 0d9aeb2..417d147 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
@@ -38,7 +38,6 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
 import java.text.Format;
-import java.text.ParseException;
 import java.util.Properties;
 
 import org.apache.phoenix.exception.SQLExceptionCode;
@@ -55,7 +54,7 @@ public class VariableLengthPKIT extends 
BaseClientManagedTimeIT {
     private static final Date D1 = toDate(DS1);
 
     private static Date toDate(String dateString) {
-        return DateUtil.parseDateTime(dateString);
+        return DateUtil.parseDate(dateString);
     }
 
     protected static void initGroupByRowKeyColumns(long ts) throws Exception {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/it/java/org/apache/phoenix/mapreduce/CsvBulkLoadToolIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/mapreduce/CsvBulkLoadToolIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/mapreduce/CsvBulkLoadToolIT.java
index 00968ae..392395d 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/mapreduce/CsvBulkLoadToolIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/mapreduce/CsvBulkLoadToolIT.java
@@ -44,12 +44,6 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import static org.apache.phoenix.query.BaseTest.setUpConfigForMiniCluster;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
 @Category(NeedsOwnMiniClusterTest.class)
 public class CsvBulkLoadToolIT {
 
@@ -119,11 +113,11 @@ public class CsvBulkLoadToolIT {
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertEquals("Name 1", rs.getString(2));
-        assertEquals(DateUtil.parseDateTime("1970-01-01"), rs.getDate(3));
+        assertEquals(DateUtil.parseDate("1970-01-01"), rs.getDate(3));
         assertTrue(rs.next());
         assertEquals(2, rs.getInt(1));
         assertEquals("Name 2", rs.getString(2));
-        assertEquals(DateUtil.parseDateTime("1970-01-02"), rs.getDate(3));
+        assertEquals(DateUtil.parseDate("1970-01-02"), rs.getDate(3));
         assertFalse(rs.next());
 
         rs.close();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
index f48f613..d726488 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
@@ -60,8 +60,12 @@ public class StatementContext {
     private final ExpressionManager expressions;
     private final AggregationManager aggregates;
     private final String dateFormat;
-    private final TimeZone dateFormatTimeZone;
     private final Format dateFormatter;
+    private final String timeFormat;
+    private final Format timeFormatter;
+    private final String timestampFormat;
+    private final Format timestampFormatter;
+    private final TimeZone dateFormatTimeZone;
     private final String numberFormat;
     private final ImmutableBytesWritable tempPtr;
     private final PhoenixStatement statement;
@@ -99,9 +103,13 @@ public class StatementContext {
         this.expressions = new ExpressionManager();
         PhoenixConnection connection = statement.getConnection();
         this.dateFormat = 
connection.getQueryServices().getProps().get(QueryServices.DATE_FORMAT_ATTRIB, 
DateUtil.DEFAULT_DATE_FORMAT);
+        this.dateFormatter = DateUtil.getDateFormatter(dateFormat);
+        this.timeFormat = 
connection.getQueryServices().getProps().get(QueryServices.TIME_FORMAT_ATTRIB, 
DateUtil.DEFAULT_TIME_FORMAT);
+        this.timeFormatter = DateUtil.getTimeFormatter(timeFormat);
+        this.timestampFormat = 
connection.getQueryServices().getProps().get(QueryServices.TIMESTAMP_FORMAT_ATTRIB,
 DateUtil.DEFAULT_TIMESTAMP_FORMAT);
+        this.timestampFormatter = 
DateUtil.getTimestampFormatter(timestampFormat);
         this.dateFormatTimeZone = TimeZone.getTimeZone(
                 
connection.getQueryServices().getProps().get(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB,
 DateUtil.DEFAULT_TIME_ZONE_ID));
-        this.dateFormatter = DateUtil.getDateFormatter(dateFormat);
         this.numberFormat = 
connection.getQueryServices().getProps().get(QueryServices.NUMBER_FORMAT_ATTRIB,
 NumberUtil.DEFAULT_NUMBER_FORMAT);
         this.tempPtr = new ImmutableBytesWritable();
         this.currentTable = resolver != null && 
!resolver.getTables().isEmpty() ? resolver.getTables().get(0) : null;
@@ -151,6 +159,22 @@ public class StatementContext {
         return dateFormatter;
     }
 
+    public String getTimeFormat() {
+        return timeFormat;
+    }
+
+    public Format getTimeFormatter() {
+        return timeFormatter;
+    }
+
+    public String getTimestampFormat() {
+        return timestampFormat;
+    }
+
+    public Format getTimestampFormatter() {
+        return timestampFormatter;
+    }
+
     public String getNumberFormat() {
         return numberFormat;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
index 706a751..cbbfe4a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
@@ -21,6 +21,7 @@ import java.util.Map;
 
 import org.apache.phoenix.expression.function.ArrayAllComparisonExpression;
 import org.apache.phoenix.expression.function.ArrayAnyComparisonExpression;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
 import org.apache.phoenix.expression.function.ArrayIndexFunction;
 import org.apache.phoenix.expression.function.ArrayLengthFunction;
 import org.apache.phoenix.expression.function.CeilDateExpression;
@@ -40,7 +41,6 @@ import 
org.apache.phoenix.expression.function.FloorDateExpression;
 import org.apache.phoenix.expression.function.FloorDecimalExpression;
 import org.apache.phoenix.expression.function.FloorFunction;
 import org.apache.phoenix.expression.function.IndexStateNameFunction;
-import org.apache.phoenix.expression.function.ArrayElemRefExpression;
 import org.apache.phoenix.expression.function.InvertFunction;
 import org.apache.phoenix.expression.function.LTrimFunction;
 import org.apache.phoenix.expression.function.LastValueFunction;
@@ -76,6 +76,8 @@ import 
org.apache.phoenix.expression.function.TimezoneOffsetFunction;
 import org.apache.phoenix.expression.function.ToCharFunction;
 import org.apache.phoenix.expression.function.ToDateFunction;
 import org.apache.phoenix.expression.function.ToNumberFunction;
+import org.apache.phoenix.expression.function.ToTimeFunction;
+import org.apache.phoenix.expression.function.ToTimestampFunction;
 import org.apache.phoenix.expression.function.TrimFunction;
 import org.apache.phoenix.expression.function.TruncFunction;
 import org.apache.phoenix.expression.function.UpperFunction;
@@ -187,7 +189,11 @@ public enum ExpressionType {
     ModulusExpression(ModulusExpression.class),
     DistinctValueAggregateFunction(DistinctValueAggregateFunction.class),
     RegexpSplitFunctiond(RegexpSplitFunction.class),
-    RandomFunction(RandomFunction.class);
+    RandomFunction(RandomFunction.class),
+    ToTimeFunction(ToTimeFunction.class),
+    ToTimestampFunction(ToTimestampFunction.class),
+    ;
+    
     ExpressionType(Class<? extends Expression> clazz) {
         this.clazz = clazz;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java
index 73ca3ed..01b0dfd 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java
@@ -17,24 +17,23 @@
  */
 package org.apache.phoenix.expression.function;
 
-import java.io.*;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
 import java.sql.SQLException;
-import java.text.Format;
-import java.text.ParseException;
 import java.util.List;
 
-import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.io.WritableUtils;
-
 import org.apache.phoenix.expression.Expression;
-import org.apache.phoenix.parse.*;
+import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
-import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.parse.ToDateParseNode;
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PDate;
 import org.apache.phoenix.schema.types.PVarchar;
-import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.DateUtil;
 
 
@@ -46,7 +45,6 @@ import org.apache.phoenix.util.DateUtil;
  * valid (constant) timezone id, or the string "local". The third argument is 
also optional, and
  * it defaults to GMT.
  *
- * @since 0.1
  */
 @BuiltInFunction(name=ToDateFunction.NAME, nodeClass=ToDateParseNode.class,
         args={@Argument(allowedTypes={PVarchar.class}),
@@ -56,33 +54,47 @@ public class ToDateFunction extends ScalarFunction {
     public static final String NAME = "TO_DATE";
     private DateUtil.DateTimeParser dateParser;
     private String dateFormat;
+    private String timeZoneId;
 
     public ToDateFunction() {
     }
 
-    public ToDateFunction(List<Expression> children, String dateFormat, 
DateUtil.DateTimeParser dateParser) throws SQLException {
-        super(children.subList(0, 1));
+    public ToDateFunction(List<Expression> children, String dateFormat, String 
timeZoneId) throws SQLException {
+        super(children);
+        init(dateFormat, timeZoneId);
+    }
+    
+    private void init(String dateFormat, String timeZoneId) {
         this.dateFormat = dateFormat;
-        this.dateParser = dateParser;
+        this.dateParser = DateUtil.getDateTimeParser(dateFormat, 
getDataType(), timeZoneId);
+        // Store resolved timeZoneId, as if it's LOCAL, we don't want the
+        // server to evaluate using the local time zone. Instead, we want
+        // to use the client local time zone.
+        this.timeZoneId = this.dateParser.getTimeZone().getID();
     }
 
     @Override
     public int hashCode() {
         final int prime = 31;
-        int result = 1;
-        result = prime * result + dateFormat.hashCode();
-        result = prime * result + getExpression().hashCode();
+        int result = super.hashCode();
+        result = prime * result + ((dateFormat == null) ? 0 : 
dateFormat.hashCode());
+        result = prime * result + ((timeZoneId == null) ? 0 : 
timeZoneId.hashCode());
         return result;
     }
 
     @Override
     public boolean equals(Object obj) {
         if (this == obj) return true;
-        if (obj == null) return false;
         if (getClass() != obj.getClass()) return false;
         ToDateFunction other = (ToDateFunction)obj;
-        if (!getExpression().equals(other.getExpression())) return false;
-        if (!dateFormat.equals(other.dateFormat)) return false;
+        // Only compare first child, as the other two are potentially resolved 
on the fly.
+        if (!this.getChildren().get(0).equals(other.getChildren().get(0))) 
return false;
+        if (dateFormat == null) {
+            if (other.dateFormat != null) return false;
+        } else if (!dateFormat.equals(other.dateFormat)) return false;
+        if (timeZoneId == null) {
+            if (other.timeZoneId != null) return false;
+        } else if (!timeZoneId.equals(other.timeZoneId)) return false;
         return true;
     }
 
@@ -94,8 +106,10 @@ public class ToDateFunction extends ScalarFunction {
         }
         PDataType type = expression.getDataType();
         String dateStr = (String)type.toObject(ptr, expression.getSortOrder());
-        Object value = dateParser.parseDateTime(dateStr);
-        byte[] byteValue = getDataType().toBytes(value);
+        long epochTime = dateParser.parseDateTime(dateStr);
+        PDataType returnType = getDataType();
+        byte[] byteValue = new byte[returnType.getByteSize()];
+        returnType.getCodec().encodeLong(epochTime, byteValue, 0);
         ptr.set(byteValue);
         return true;
      }
@@ -110,17 +124,50 @@ public class ToDateFunction extends ScalarFunction {
         return getExpression().isNullable();
     }
 
+    private String getTimeZoneIdArg() {
+        return children.size() < 3 ? null : (String) ((LiteralExpression) 
children.get(2)).getValue();
+    }
+    
+    private String getDateFormatArg() {
+        return children.size() < 2 ? null : (String) ((LiteralExpression) 
children.get(1)).getValue();
+    }
+    
     @Override
     public void readFields(DataInput input) throws IOException {
         super.readFields(input);
-        dateFormat = WritableUtils.readString(input);
-        dateParser = DateUtil.getDateParser(dateFormat);
+        String timeZoneId;
+        String dateFormat = WritableUtils.readString(input);  
+        if (dateFormat.length() != 0) { // pre 4.3
+            timeZoneId = DateUtil.DEFAULT_TIME_ZONE_ID;         
+        } else {
+            int nChildren = children.size();
+            if (nChildren == 1) {
+                dateFormat = WritableUtils.readString(input); 
+                timeZoneId =  WritableUtils.readString(input);
+            } else if (nChildren == 2 || 
DateUtil.LOCAL_TIME_ZONE_ID.equalsIgnoreCase(getTimeZoneIdArg())) {
+                dateFormat = getDateFormatArg();
+                timeZoneId =  WritableUtils.readString(input);
+            } else {
+                dateFormat = getDateFormatArg();
+                timeZoneId =  getTimeZoneIdArg();
+            }
+        }
+        init(dateFormat, timeZoneId);
     }
 
     @Override
     public void write(DataOutput output) throws IOException {
         super.write(output);
-        WritableUtils.writeString(output, dateFormat);
+        WritableUtils.writeString(output, ""); // For b/w compat
+        int nChildren = children.size();
+        // If dateFormat and/or timeZoneId are supplied as children, don't 
write them again,
+        // except if using LOCAL, in which case we want to write the 
resolved/actual time zone.
+        if (nChildren == 1) {
+            WritableUtils.writeString(output, dateFormat);
+            WritableUtils.writeString(output, timeZoneId);
+        } else if (nChildren == 2 || 
DateUtil.LOCAL_TIME_ZONE_ID.equalsIgnoreCase(getTimeZoneIdArg())) {
+            WritableUtils.writeString(output, timeZoneId);
+        }
     }
 
     private Expression getExpression() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java
new file mode 100644
index 0000000..3a26584
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.phoenix.expression.function;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.ToTimeParseNode;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PTime;
+import org.apache.phoenix.schema.types.PVarchar;
+
+/**
+*
+* Implementation of the {@code 
TO_TIME(<string>,[<format-string>,[<timezone-string>]])} built-in function.
+* The second argument is optional and defaults to the phoenix.query.dateFormat 
value
+* from the HBase config. If present it must be a constant string. The third 
argument is either a
+* valid (constant) timezone id, or the string "LOCAL". The third argument is 
also optional, and
+* it defaults to GMT.
+*
+*/
+@BuiltInFunction(name=ToTimeFunction.NAME, nodeClass=ToTimeParseNode.class,
+       args={@Argument(allowedTypes={PVarchar.class}),
+               
@Argument(allowedTypes={PVarchar.class},isConstant=true,defaultValue="null"),
+               @Argument(allowedTypes={PVarchar.class}, isConstant=true, 
defaultValue = "null") } )
+public class ToTimeFunction extends ToDateFunction {
+    public static final String NAME = "TO_TIME";
+
+    public ToTimeFunction() {
+    }
+
+    public ToTimeFunction(List<Expression> children, String dateFormat, String 
timeZoneId) throws SQLException {
+        super(children, dateFormat, timeZoneId);
+    }
+
+    @Override
+    public PDataType getDataType() {
+        return PTime.INSTANCE;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java
new file mode 100644
index 0000000..17643a2
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.phoenix.expression.function;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.ToTimestampParseNode;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PTimestamp;
+import org.apache.phoenix.schema.types.PVarchar;
+
+/**
+*
+* Implementation of the {@code 
TO_TIMESTAMP(<string>,[<format-string>,[<timezone-string>]])} built-in function.
+* The second argument is optional and defaults to the 
phoenix.query.timestampFormat value
+* from the HBase config. If present it must be a constant string. The third 
argument is either a
+* valid (constant) timezone id, or the string "local". The third argument is 
also optional, and
+* it defaults to GMT.
+*
+*/
+@BuiltInFunction(name=ToTimestampFunction.NAME, 
nodeClass=ToTimestampParseNode.class,
+       args={@Argument(allowedTypes={PVarchar.class}),
+               
@Argument(allowedTypes={PVarchar.class},isConstant=true,defaultValue="null"),
+               @Argument(allowedTypes={PVarchar.class}, isConstant=true, 
defaultValue = "null") } )
+public class ToTimestampFunction extends ToDateFunction {
+    public static final String NAME = "TO_TIMESTAMP";
+
+    public ToTimestampFunction() {
+    }
+
+    public ToTimestampFunction(List<Expression> children, String dateFormat, 
String timeZoneId) throws SQLException {
+        super(children, dateFormat, timeZoneId);
+    }
+
+    @Override
+    public PDataType getDataType() {
+        return PTimestamp.INSTANCE;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java 
b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index b778a57..de9e323 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -128,6 +128,8 @@ public class PhoenixConnection implements Connection, 
org.apache.phoenix.jdbc.Jd
     private PMetaData metaData;
     private final PName tenantId;
     private final String datePattern;
+    private final String timePattern;
+    private final String timestampPattern;
     
     private boolean isClosed = false;
     private Sampler<?> sampler;
@@ -204,15 +206,19 @@ public class PhoenixConnection implements Connection, 
org.apache.phoenix.jdbc.Jd
         this.tenantId = tenantId;
         this.mutateBatchSize = JDBCUtil.getMutateBatchSize(url, this.info, 
this.services.getProps());
         datePattern = 
this.services.getProps().get(QueryServices.DATE_FORMAT_ATTRIB, 
DateUtil.DEFAULT_DATE_FORMAT);
+        timePattern = 
this.services.getProps().get(QueryServices.TIME_FORMAT_ATTRIB, 
DateUtil.DEFAULT_TIME_FORMAT);
+        timestampPattern = 
this.services.getProps().get(QueryServices.TIMESTAMP_FORMAT_ATTRIB, 
DateUtil.DEFAULT_TIMESTAMP_FORMAT);
         String numberPattern = 
this.services.getProps().get(QueryServices.NUMBER_FORMAT_ATTRIB, 
NumberUtil.DEFAULT_NUMBER_FORMAT);
         int maxSize = 
this.services.getProps().getInt(QueryServices.MAX_MUTATION_SIZE_ATTRIB,QueryServicesOptions.DEFAULT_MAX_MUTATION_SIZE);
-        Format dateTimeFormat = DateUtil.getDateFormatter(datePattern);
-        formatters.put(PDate.INSTANCE, dateTimeFormat);
-        formatters.put(PTime.INSTANCE, dateTimeFormat);
-        formatters.put(PTimestamp.INSTANCE, dateTimeFormat);
-        formatters.put(PUnsignedDate.INSTANCE, dateTimeFormat);
-        formatters.put(PUnsignedTime.INSTANCE, dateTimeFormat);
-        formatters.put(PUnsignedTimestamp.INSTANCE, dateTimeFormat);
+        Format dateFormat = DateUtil.getDateFormatter(datePattern);
+        Format timeFormat = DateUtil.getDateFormatter(timePattern);
+        Format timestampFormat = DateUtil.getDateFormatter(timestampPattern);
+        formatters.put(PDate.INSTANCE, dateFormat);
+        formatters.put(PTime.INSTANCE, timeFormat);
+        formatters.put(PTimestamp.INSTANCE, timestampFormat);
+        formatters.put(PUnsignedDate.INSTANCE, dateFormat);
+        formatters.put(PUnsignedTime.INSTANCE, timeFormat);
+        formatters.put(PUnsignedTimestamp.INSTANCE, timestampFormat);
         formatters.put(PDecimal.INSTANCE, 
FunctionArgumentType.NUMERIC.getFormatter(numberPattern));
         // We do not limit the metaData on a connection less than the global 
one,
         // as there's not much that will be cached here.

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java 
b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java
index 6140dbc..fd4d16a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java
@@ -18,16 +18,13 @@
 package org.apache.phoenix.parse;
 
 import java.sql.SQLException;
-import java.text.Format;
 import java.util.List;
-import java.util.TimeZone;
 
 import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.expression.function.FunctionExpression;
 import org.apache.phoenix.expression.function.ToDateFunction;
-import org.apache.phoenix.util.DateUtil;
 
 
 public class ToDateParseNode extends FunctionParseNode {
@@ -46,7 +43,6 @@ public class ToDateParseNode extends FunctionParseNode {
         if (timeZoneId == null) {
             timeZoneId = context.getDateFormatTimeZone().getID();
         }
-        DateUtil.DateTimeParser dateParser = 
DateUtil.getDateParser(dateFormat, timeZoneId);
-        return new ToDateFunction(children, dateFormat, dateParser);
+        return new ToDateFunction(children, dateFormat, timeZoneId);
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/parse/ToTimeParseNode.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/parse/ToTimeParseNode.java 
b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToTimeParseNode.java
new file mode 100644
index 0000000..5f0a72d
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToTimeParseNode.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.expression.function.ToTimeFunction;
+
+
+public class ToTimeParseNode extends FunctionParseNode { 
+
+    public ToTimeParseNode(String name, List<ParseNode> children, 
BuiltInFunctionInfo info) {
+        super(name, children, info);
+    }
+
+    @Override
+    public FunctionExpression create(List<Expression> children, 
StatementContext context) throws SQLException {
+        String dateFormat = (String) ((LiteralExpression) 
children.get(1)).getValue();
+        String timeZoneId = (String) ((LiteralExpression) 
children.get(2)).getValue();
+        if (dateFormat == null) {
+            dateFormat = context.getTimeFormat();
+        }
+        if (timeZoneId == null) {
+            timeZoneId = context.getDateFormatTimeZone().getID();
+        }
+        return new ToTimeFunction(children, dateFormat, timeZoneId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/parse/ToTimestampParseNode.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/parse/ToTimestampParseNode.java 
b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToTimestampParseNode.java
new file mode 100644
index 0000000..2a3f5ec
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToTimestampParseNode.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.expression.function.ToTimestampFunction;
+
+
+public class ToTimestampParseNode extends FunctionParseNode { 
+
+    public ToTimestampParseNode(String name, List<ParseNode> children, 
BuiltInFunctionInfo info) {
+        super(name, children, info);
+    }
+
+    @Override
+    public FunctionExpression create(List<Expression> children, 
StatementContext context) throws SQLException {
+        String dateFormat = (String) ((LiteralExpression) 
children.get(1)).getValue();
+        String timeZoneId = (String) ((LiteralExpression) 
children.get(2)).getValue();
+        if (dateFormat == null) {
+            dateFormat = context.getTimestampFormat();
+        }
+        if (timeZoneId == null) {
+            timeZoneId = context.getDateFormatTimeZone().getID();
+        }
+        return new ToTimestampFunction(children, dateFormat, timeZoneId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java 
b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
index d21695d..e20d5ee 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
@@ -71,6 +71,9 @@ public interface QueryServices extends SQLCloseable {
     public static final String MAX_SERVER_CACHE_SIZE_ATTRIB = 
"phoenix.query.maxServerCacheBytes";
     public static final String DATE_FORMAT_TIMEZONE_ATTRIB = 
"phoenix.query.dateFormatTimeZone";
     public static final String DATE_FORMAT_ATTRIB = "phoenix.query.dateFormat";
+    public static final String TIME_FORMAT_ATTRIB = "phoenix.query.timeFormat";
+    public static final String TIMESTAMP_FORMAT_ATTRIB = 
"phoenix.query.timestampFormat";
+
     public static final String NUMBER_FORMAT_ATTRIB = 
"phoenix.query.numberFormat";
     public static final String CALL_QUEUE_ROUND_ROBIN_ATTRIB = 
"ipc.server.callqueue.roundrobin";
     public static final String SCAN_CACHE_SIZE_ATTRIB = 
"hbase.client.scanner.caching";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java
index 13a828f..bbd0a35 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java
@@ -17,16 +17,16 @@
  */
 package org.apache.phoenix.schema.types;
 
-import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.phoenix.schema.SortOrder;
-import org.apache.phoenix.util.DateUtil;
-
 import java.math.BigDecimal;
 import java.sql.Date;
 import java.sql.Types;
 import java.text.Format;
 
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.util.DateUtil;
+
 public class PDate extends PDataType<Date> {
 
   public static final PDate INSTANCE = new PDate();
@@ -71,7 +71,7 @@ public class PDate extends PDataType<Date> {
     } else if (actualType == PDecimal.INSTANCE) {
       return new Date(((BigDecimal) object).longValueExact());
     } else if (actualType == PVarchar.INSTANCE) {
-      return DateUtil.parseDateTime((String) object);
+      return DateUtil.parseDate((String) object);
     }
     return throwConstraintViolationException(actualType, this);
   }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java
index d824885..81cbaff 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java
@@ -17,15 +17,15 @@
  */
 package org.apache.phoenix.schema.types;
 
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.phoenix.schema.SortOrder;
-import org.apache.phoenix.util.DateUtil;
-
 import java.math.BigDecimal;
 import java.sql.Time;
 import java.sql.Types;
 import java.text.Format;
 
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.util.DateUtil;
+
 public class PTime extends PDataType<Time> {
 
   public static final PTime INSTANCE = new PTime();
@@ -78,7 +78,7 @@ public class PTime extends PDataType<Time> {
     } else if (actualType == PDecimal.INSTANCE) {
       return new java.sql.Time(((BigDecimal) object).longValueExact());
     } else if (actualType == PVarchar.INSTANCE) {
-      return DateUtil.parseDateTime((String) object);
+      return DateUtil.parseTime((String) object);
     }
     return throwConstraintViolationException(actualType, this);
   }
@@ -128,8 +128,10 @@ public class PTime extends PDataType<Time> {
 
   @Override
   public String toStringLiteral(byte[] b, int offset, int length, Format 
formatter) {
-    // TODO: different default formatter for TIME?
-    return PDate.INSTANCE.toStringLiteral(b, offset, length, formatter);
+      if (formatter == null) {
+          formatter = DateUtil.DEFAULT_TIME_FORMATTER;
+        }
+        return "'" + super.toStringLiteral(b, offset, length, formatter) + "'";
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java
index 4bdcb86..8182e33 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java
@@ -17,17 +17,17 @@
  */
 package org.apache.phoenix.schema.types;
 
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.text.Format;
+
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.util.DateUtil;
 
-import java.math.BigDecimal;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.text.Format;
-
 public class PTimestamp extends PDataType<Timestamp> {
 
   public static final PTimestamp INSTANCE = new PTimestamp();
@@ -84,7 +84,7 @@ public class PTimestamp extends PDataType<Timestamp> {
               .intValue();
       return DateUtil.getTimestamp(ms, nanos);
     } else if (actualType == PVarchar.INSTANCE) {
-      return new Timestamp(DateUtil.parseDateTime((String) object).getTime());
+      return DateUtil.parseTimestamp((String) object);
     }
     return throwConstraintViolationException(actualType, this);
   }
@@ -181,15 +181,13 @@ public class PTimestamp extends PDataType<Timestamp> {
 
   @Override
   public String toStringLiteral(byte[] b, int offset, int length, Format 
formatter) {
-    java.sql.Timestamp value = (java.sql.Timestamp) toObject(b, offset, 
length);
-    if (formatter == null || formatter == DateUtil.DEFAULT_DATE_FORMATTER) {
-      // If default formatter has not been overridden,
-      // use one that displays milliseconds.
-      formatter = DateUtil.DEFAULT_MS_DATE_FORMATTER;
-    }
-    return "'" + super.toStringLiteral(b, offset, length, formatter) + "." + 
value.getNanos() + "'";
+      if (formatter == null) {
+          formatter = DateUtil.DEFAULT_TIMESTAMP_FORMATTER;
+        }
+        return "'" + super.toStringLiteral(b, offset, length, formatter) + "'";
   }
 
+
   @Override
   public int getNanos(ImmutableBytesWritable ptr, SortOrder sortOrder) {
     int nanos = PUnsignedInt.INSTANCE.getCodec()

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java 
b/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java
index fbc74ba..0f4b54a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java
@@ -21,85 +21,122 @@ import java.math.BigDecimal;
 import java.sql.Date;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.sql.Types;
 import java.text.Format;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.util.List;
 import java.util.TimeZone;
 
 import org.apache.commons.lang.time.FastDateFormat;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.IllegalDataException;
+import org.apache.phoenix.schema.types.PDataType;
+import org.joda.time.DateTimeZone;
 import org.joda.time.chrono.ISOChronology;
 import org.joda.time.format.DateTimeFormatter;
 import org.joda.time.format.DateTimeFormatterBuilder;
 import org.joda.time.format.ISODateTimeFormat;
 
+import com.google.common.collect.Lists;
 
-@SuppressWarnings("serial")
+
+@SuppressWarnings({ "serial", "deprecation" })
 public class DateUtil {
     public static final String DEFAULT_TIME_ZONE_ID = "GMT";
+    public static final String LOCAL_TIME_ZONE_ID = "LOCAL";
     private static final TimeZone DEFAULT_TIME_ZONE = 
TimeZone.getTimeZone(DEFAULT_TIME_ZONE_ID);
-    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; // 
This is the format the app sets in NLS settings for every connection.
-    public static final Format DEFAULT_DATE_FORMATTER = 
FastDateFormat.getInstance(
-            DEFAULT_DATE_FORMAT, TimeZone.getTimeZone(DEFAULT_TIME_ZONE_ID));
-
+    
     public static final String DEFAULT_MS_DATE_FORMAT = "yyyy-MM-dd 
HH:mm:ss.SSS";
     public static final Format DEFAULT_MS_DATE_FORMATTER = 
FastDateFormat.getInstance(
             DEFAULT_MS_DATE_FORMAT, 
TimeZone.getTimeZone(DEFAULT_TIME_ZONE_ID));
 
-    private static final DateTimeFormatter ISO_DATE_TIME_PARSER = new 
DateTimeFormatterBuilder()
-            .append(ISODateTimeFormat.dateParser())
-            .appendOptional(new DateTimeFormatterBuilder()
-                    .appendLiteral(' ').toParser())
-            .appendOptional(new DateTimeFormatterBuilder()
-                    .append(ISODateTimeFormat.timeParser()).toParser())
-            .toFormatter()
-            .withZoneUTC()
-            .withChronology(ISOChronology.getInstanceUTC());
+    public static final String DEFAULT_DATE_FORMAT = DEFAULT_MS_DATE_FORMAT;
+    public static final Format DEFAULT_DATE_FORMATTER = 
DEFAULT_MS_DATE_FORMATTER;
 
-    private DateUtil() {
-    }
+    public static final String DEFAULT_TIME_FORMAT = DEFAULT_MS_DATE_FORMAT;
+    public static final Format DEFAULT_TIME_FORMATTER = 
DEFAULT_MS_DATE_FORMATTER;
 
-    public static DateTimeParser getDateParser(String pattern, TimeZone 
timeZone) {
-        if(DateUtil.DEFAULT_DATE_FORMAT.equals(pattern) &&
-                
timeZone.getID().equalsIgnoreCase(DateUtil.DEFAULT_TIME_ZONE_ID)) {
-            return ISODateFormatParser.getInstance();
-        } else {
-            return new SimpleDateFormatParser(pattern, timeZone);
-        }
+    public static final String DEFAULT_TIMESTAMP_FORMAT = 
DEFAULT_MS_DATE_FORMAT;
+    public static final Format DEFAULT_TIMESTAMP_FORMATTER = 
DEFAULT_MS_DATE_FORMATTER;
+
+    private static final DateTimeFormatter ISO_DATE_TIME_FORMATTER = new 
DateTimeFormatterBuilder()
+        .append(ISODateTimeFormat.dateParser())
+        .appendOptional(new DateTimeFormatterBuilder()
+                .appendLiteral(' ').toParser())
+        .appendOptional(new DateTimeFormatterBuilder()
+                .append(ISODateTimeFormat.timeParser()).toParser())
+        .toFormatter().withChronology(ISOChronology.getInstanceUTC());
+    
+    private DateUtil() {
     }
 
-    public static DateTimeParser getDateParser(String pattern, String 
timeZoneId) {
-        if(timeZoneId == null) {
-            timeZoneId = DateUtil.DEFAULT_TIME_ZONE_ID;
-        }
+    private static TimeZone getTimeZone(String timeZoneId) {
         TimeZone parserTimeZone;
-        if ("LOCAL".equalsIgnoreCase(timeZoneId)) {
+        if (timeZoneId == null) {
+            parserTimeZone = DateUtil.DEFAULT_TIME_ZONE;
+        } else if (LOCAL_TIME_ZONE_ID.equalsIgnoreCase(timeZoneId)) {
             parserTimeZone = TimeZone.getDefault();
         } else {
             parserTimeZone = TimeZone.getTimeZone(timeZoneId);
         }
-        return getDateParser(pattern, parserTimeZone);
+        return parserTimeZone;
     }
-
-    public static DateTimeParser getDateParser(String pattern) {
-        return getDateParser(pattern, DEFAULT_TIME_ZONE);
-    }
-
-    public static DateTimeParser getTimeParser(String pattern, TimeZone 
timeZone) {
-        return getDateParser(pattern, timeZone);
+    
+    private static String[] defaultPattern;
+    static {
+        int maxOrdinal = Integer.MIN_VALUE;
+        List<PDataType> timeDataTypes = Lists.newArrayListWithExpectedSize(6);
+        for (PDataType type : PDataType.values()) {
+            if (java.util.Date.class.isAssignableFrom(type.getJavaClass())) {
+                timeDataTypes.add(type);
+                if (type.ordinal() > maxOrdinal) {
+                    maxOrdinal = type.ordinal();
+                }
+            }
+        }
+        defaultPattern = new String[maxOrdinal+1];
+        for (PDataType type : timeDataTypes) {
+            switch (type.getResultSetSqlType()) {
+            case Types.TIMESTAMP:
+                defaultPattern[type.ordinal()] = 
DateUtil.DEFAULT_TIMESTAMP_FORMAT;
+                break;
+            case Types.TIME:
+                defaultPattern[type.ordinal()] = DateUtil.DEFAULT_TIME_FORMAT;
+                break;
+            case Types.DATE:
+                defaultPattern[type.ordinal()] = DateUtil.DEFAULT_DATE_FORMAT;
+                break;
+            }
+        }
     }
-
-    public static DateTimeParser getTimeParser(String pattern) {
-        return getTimeParser(pattern, DEFAULT_TIME_ZONE);
+    
+    private static String getDefaultFormat(PDataType type) {
+        int ordinal = type.ordinal();
+        if (ordinal >= 0 || ordinal < defaultPattern.length) {
+            String format = defaultPattern[ordinal];
+            if (format != null) {
+                return format;
+            }
+        }
+        throw new IllegalArgumentException("Expected a date/time type, but got 
" + type);
     }
 
-    public static DateTimeParser getTimestampParser(String pattern, TimeZone 
timeZone) {
-        return getDateParser(pattern, timeZone);
+    public static DateTimeParser getDateTimeParser(String pattern, PDataType 
pDataType, String timeZoneId) {
+        TimeZone timeZone = getTimeZone(timeZoneId);
+        String defaultPattern = getDefaultFormat(pDataType);
+        if (pattern == null || pattern.length() == 0) {
+            pattern = defaultPattern;
+        }
+        if(defaultPattern.equals(pattern)) {
+            return ISODateFormatParserFactory.getParser(timeZone);
+        } else {
+            return new SimpleDateFormatParser(pattern, timeZone);
+        }
     }
 
-    public static DateTimeParser getTimestampParser(String pattern) {
-        return getTimestampParser(pattern, DEFAULT_TIME_ZONE);
+    public static DateTimeParser getDateTimeParser(String pattern, PDataType 
pDataType) {
+        return getDateTimeParser(pattern, pDataType, null);
     }
 
     public static Format getDateFormatter(String pattern) {
@@ -108,20 +145,32 @@ public class DateUtil {
                 : FastDateFormat.getInstance(pattern, 
DateUtil.DEFAULT_TIME_ZONE);
     }
 
-    public static Date parseDateTime(String dateTimeValue) {
+    public static Format getTimeFormatter(String pattern) {
+        return DateUtil.DEFAULT_TIME_FORMAT.equals(pattern)
+                ? DateUtil.DEFAULT_TIME_FORMATTER
+                : FastDateFormat.getInstance(pattern, 
DateUtil.DEFAULT_TIME_ZONE);
+    }
+
+    public static Format getTimestampFormatter(String pattern) {
+        return DateUtil.DEFAULT_TIMESTAMP_FORMAT.equals(pattern)
+                ? DateUtil.DEFAULT_TIMESTAMP_FORMATTER
+                : FastDateFormat.getInstance(pattern, 
DateUtil.DEFAULT_TIME_ZONE);
+    }
+
+    private static long parseDateTime(String dateTimeValue) {
         return ISODateFormatParser.getInstance().parseDateTime(dateTimeValue);
     }
 
     public static Date parseDate(String dateValue) {
-        return parseDateTime(dateValue);
+        return new Date(parseDateTime(dateValue));
     }
 
     public static Time parseTime(String timeValue) {
-        return new Time(parseDateTime(timeValue).getTime());
+        return new Time(parseDateTime(timeValue));
     }
 
     public static Timestamp parseTimestamp(String timestampValue) {
-        return new Timestamp(parseDateTime(timestampValue).getTime());
+        return new Timestamp(parseDateTime(timestampValue));
     }
 
     /**
@@ -145,7 +194,8 @@ public class DateUtil {
     }
 
     public static interface DateTimeParser {
-        public Date parseDateTime(String dateTimeString) throws 
IllegalDataException;
+        public long parseDateTime(String dateTimeString) throws 
IllegalDataException;
+        public TimeZone getTimeZone();
     }
 
     /**
@@ -168,41 +218,76 @@ public class DateUtil {
         }
 
         @Override
-        public Date parseDateTime(String dateTimeString) throws 
IllegalDataException {
+        public long parseDateTime(String dateTimeString) throws 
IllegalDataException {
             try {
                 java.util.Date date =parser.parse(dateTimeString);
-                return new java.sql.Date(date.getTime());
+                return date.getTime();
             } catch (ParseException e) {
-                throw new IllegalDataException("to_date('" + dateTimeString + 
"') did not match expected date format of '" + datePattern + "'.");
+                throw new IllegalDataException("Unable to parse date/time '" + 
dateTimeString + "' using format string of '" + datePattern + "'.");
             }
         }
+
+        @Override
+        public TimeZone getTimeZone() {
+            return parser.getTimeZone();
+        }
     }
 
+    private static class ISODateFormatParserFactory {
+        private ISODateFormatParserFactory() {}
+        
+        public static DateTimeParser getParser(final TimeZone timeZone) {
+            // If timeZone matches default, get singleton DateTimeParser
+            if (timeZone.equals(DEFAULT_TIME_ZONE)) {
+                return ISODateFormatParser.getInstance();
+            }
+            // Otherwise, create new DateTimeParser
+            return new DateTimeParser() {
+                private final DateTimeFormatter formatter = 
ISO_DATE_TIME_FORMATTER
+                        .withZone(DateTimeZone.forTimeZone(timeZone));
+
+                @Override
+                public long parseDateTime(String dateTimeString) throws 
IllegalDataException {
+                    try {
+                        return 
formatter.parseDateTime(dateTimeString).getMillis();
+                    } catch(IllegalArgumentException ex) {
+                        throw new IllegalDataException(ex);
+                    }
+                }
+
+                @Override
+                public TimeZone getTimeZone() {
+                    return timeZone;
+                }
+            };
+        }
+    }
     /**
      * This class is our default DateTime string parser
      */
     private static class ISODateFormatParser implements DateTimeParser {
-        private static ISODateFormatParser inst = null;
-        private static Object lock = new Object();
-        private ISODateFormatParser() {}
+        private static final ISODateFormatParser INSTANCE = new 
ISODateFormatParser();
 
         public static ISODateFormatParser getInstance() {
-            if(inst != null) return inst;
-
-            synchronized (lock) {
-                if (inst == null) {
-                    inst = new ISODateFormatParser();
-                }
-            }
-            return inst;
+            return INSTANCE;
         }
 
-        public Date parseDateTime(String dateTimeString) throws 
IllegalDataException {
+        private final DateTimeFormatter formatter = 
ISO_DATE_TIME_FORMATTER.withZoneUTC();
+
+        private ISODateFormatParser() {}
+
+        @Override
+        public long parseDateTime(String dateTimeString) throws 
IllegalDataException {
             try {
-                return new 
Date(ISO_DATE_TIME_PARSER.parseDateTime(dateTimeString).getMillis());
+                return formatter.parseDateTime(dateTimeString).getMillis();
             } catch(IllegalArgumentException ex) {
                 throw new IllegalDataException(ex);
             }
         }
+
+        @Override
+        public TimeZone getTimeZone() {
+            return formatter.getZone().toTimeZone();
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/main/java/org/apache/phoenix/util/csv/CsvUpsertExecutor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/util/csv/CsvUpsertExecutor.java 
b/phoenix-core/src/main/java/org/apache/phoenix/util/csv/CsvUpsertExecutor.java
index 731a13f..b5f6f9f 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/util/csv/CsvUpsertExecutor.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/util/csv/CsvUpsertExecutor.java
@@ -17,16 +17,22 @@
  */
 package org.apache.phoenix.util.csv;
 
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
+import java.io.Closeable;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.List;
+import java.util.Properties;
+
+import javax.annotation.Nullable;
+
 import org.apache.commons.csv.CSVRecord;
-import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
 import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.types.PDate;
-import org.apache.phoenix.schema.types.PTime;
 import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.util.ColumnInfo;
 import org.apache.phoenix.util.DateUtil;
@@ -34,16 +40,8 @@ import org.apache.phoenix.util.QueryUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
-import java.io.Closeable;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.Properties;
-import java.util.TimeZone;
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
 
 /**
  * Executes upsert statements on a provided {@code PreparedStatement} based on 
incoming CSV records, notifying a
@@ -205,12 +203,23 @@ public class CsvUpsertExecutor implements Closeable {
                 throw new RuntimeException(e);
             }
             this.dataType = dataType;
-            if(dataType.equals(PDate.INSTANCE) || 
dataType.equals(PTime.INSTANCE) || dataType.equals(PTimestamp.INSTANCE)) {
-                String dateFormat = 
props.getProperty(QueryServices.DATE_FORMAT_ATTRIB,
-                        QueryServicesOptions.DEFAULT_DATE_FORMAT);
+            if(dataType.isCoercibleTo(PTimestamp.INSTANCE)) {
+                // TODO: move to DateUtil
+                String dateFormat;
+                int dateSqlType = dataType.getResultSetSqlType();
+                if (dateSqlType == Types.DATE) {
+                    dateFormat = 
props.getProperty(QueryServices.DATE_FORMAT_ATTRIB,
+                            DateUtil.DEFAULT_DATE_FORMAT);
+                } else if (dateSqlType == Types.TIME) {
+                    dateFormat = 
props.getProperty(QueryServices.TIME_FORMAT_ATTRIB,
+                            DateUtil.DEFAULT_TIME_FORMAT);
+                } else {
+                    dateFormat = 
props.getProperty(QueryServices.TIMESTAMP_FORMAT_ATTRIB,
+                            DateUtil.DEFAULT_TIMESTAMP_FORMAT);                
    
+                }
                 String timeZoneId = 
props.getProperty(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB,
                         QueryServicesOptions.DEFAULT_DATE_FORMAT_TIMEZONE);
-                this.dateTimeParser = DateUtil.getDateParser(dateFormat, 
timeZoneId);
+                this.dateTimeParser = DateUtil.getDateTimeParser(dateFormat, 
dataType, timeZoneId);
             } else {
                 this.dateTimeParser = null;
             }
@@ -220,7 +229,10 @@ public class CsvUpsertExecutor implements Closeable {
         @Override
         public Object apply(@Nullable String input) {
             if(dateTimeParser != null) {
-                return dateTimeParser.parseDateTime(input);
+                long epochTime = dateTimeParser.parseDateTime(input);
+                byte[] byteValue = new byte[dataType.getByteSize()];
+                dataType.getCodec().encodeLong(epochTime, byteValue, 0);
+                return dataType.toObject(byteValue);
             }
             return dataType.toObject(input);
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java 
b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
index 6dbd303..69c1bbf 100644
--- 
a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
+++ 
b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
@@ -37,9 +37,9 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.math.BigDecimal;
+import java.sql.Date;
 import java.sql.DriverManager;
 import java.sql.SQLException;
-import java.text.Format;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -60,11 +60,11 @@ import org.apache.phoenix.query.BaseConnectionlessQueryTest;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.query.QueryServicesOptions;
+import org.apache.phoenix.schema.RowKeyValueAccessor;
+import org.apache.phoenix.schema.SaltingUtil;
 import org.apache.phoenix.schema.types.PChar;
 import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.schema.types.PVarchar;
-import org.apache.phoenix.schema.RowKeyValueAccessor;
-import org.apache.phoenix.schema.SaltingUtil;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.DateUtil;
 import org.apache.phoenix.util.NumberUtil;
@@ -277,7 +277,7 @@ public class WhereCompilerTest extends 
BaseConnectionlessQueryTest {
         Scan scan = plan.getContext().getScan();
         Filter filter = scan.getFilter();
 
-        Object date = DateUtil.parseDateTime(dateStr);
+        Date date = DateUtil.parseDate(dateStr);
 
         assertEquals(
             singleKVFilter(constantComparison(

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/test/java/org/apache/phoenix/expression/SortOrderExpressionTest.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/test/java/org/apache/phoenix/expression/SortOrderExpressionTest.java
 
b/phoenix-core/src/test/java/org/apache/phoenix/expression/SortOrderExpressionTest.java
index f75bb3e..8fb1a6c 100644
--- 
a/phoenix-core/src/test/java/org/apache/phoenix/expression/SortOrderExpressionTest.java
+++ 
b/phoenix-core/src/test/java/org/apache/phoenix/expression/SortOrderExpressionTest.java
@@ -30,22 +30,6 @@ import java.util.TimeZone;
 
 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-import org.apache.phoenix.schema.types.PChar;
-import org.apache.phoenix.schema.types.PDecimal;
-import org.apache.phoenix.schema.types.PBoolean;
-import org.apache.phoenix.schema.types.PDate;
-import org.apache.phoenix.schema.types.PDouble;
-import org.apache.phoenix.schema.types.PFloat;
-import org.apache.phoenix.schema.types.PInteger;
-import org.apache.phoenix.schema.types.PLong;
-import org.apache.phoenix.schema.types.PUnsignedDouble;
-import org.apache.phoenix.schema.types.PUnsignedFloat;
-import org.apache.phoenix.schema.types.PUnsignedInt;
-import org.apache.phoenix.schema.types.PUnsignedLong;
-import org.apache.phoenix.schema.types.PVarchar;
-import org.junit.Test;
-
-import com.google.common.collect.Lists;
 import org.apache.phoenix.expression.function.FunctionArgumentType;
 import org.apache.phoenix.expression.function.LTrimFunction;
 import org.apache.phoenix.expression.function.LengthFunction;
@@ -63,8 +47,24 @@ import 
org.apache.phoenix.expression.function.ToNumberFunction;
 import org.apache.phoenix.expression.function.TrimFunction;
 import org.apache.phoenix.expression.function.UpperFunction;
 import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.types.PBoolean;
+import org.apache.phoenix.schema.types.PChar;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.schema.types.PDecimal;
+import org.apache.phoenix.schema.types.PDouble;
+import org.apache.phoenix.schema.types.PFloat;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.schema.types.PUnsignedDouble;
+import org.apache.phoenix.schema.types.PUnsignedFloat;
+import org.apache.phoenix.schema.types.PUnsignedInt;
+import org.apache.phoenix.schema.types.PUnsignedLong;
+import org.apache.phoenix.schema.types.PVarchar;
 import org.apache.phoenix.util.DateUtil;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
 
 /**
  * @since 1.2
@@ -148,7 +148,7 @@ public class SortOrderExpressionTest {
     @Test
     public void toDate() throws Exception {
         List<Expression> args = 
Lists.newArrayList(getInvertedLiteral("2001-11-30 00:00:00:0", 
PVarchar.INSTANCE));
-        evaluateAndAssertResult(new ToDateFunction(args, null, 
DateUtil.getDateParser("yyyy-MM-dd HH:mm:ss:S")), date(11, 30, 2001));
+        evaluateAndAssertResult(new ToDateFunction(args, "yyyy-MM-dd 
HH:mm:ss:S",DateUtil.DEFAULT_TIME_ZONE_ID), date(11, 30, 2001));
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/phoenix/blob/11a76b29/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java 
b/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java
index 702e556..ec0bc01 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java
@@ -28,6 +28,9 @@ import java.text.ParseException;
 import java.util.TimeZone;
 
 import org.apache.phoenix.schema.IllegalDataException;
+import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.schema.types.PTime;
+import org.apache.phoenix.schema.types.PTimestamp;
 import org.junit.Test;
 
 /**
@@ -68,64 +71,64 @@ public class DateUtilTest {
 
     @Test
     public void testGetDateParser_DefaultTimeZone() throws ParseException {
-        Date date = 
DateUtil.getDateParser("yyyy-MM-dd").parseDateTime("1970-01-01");
+        Date date = new Date(DateUtil.getDateTimeParser("yyyy-MM-dd", 
PDate.INSTANCE).parseDateTime("1970-01-01"));
         assertEquals(0, date.getTime());
     }
 
     @Test
     public void testGetDateParser_CustomTimeZone() throws ParseException {
-        Date date = DateUtil.getDateParser(
-                "yyyy-MM-dd", 
TimeZone.getTimeZone("GMT+1")).parseDateTime("1970-01-01");
+        Date date = new Date(DateUtil.getDateTimeParser(
+                "yyyy-MM-dd", PDate.INSTANCE, 
TimeZone.getTimeZone("GMT+1").getID()).parseDateTime("1970-01-01"));
         assertEquals(-ONE_HOUR_IN_MILLIS, date.getTime());
     }
 
     @Test
     public void testGetDateParser_LocalTimeZone() throws ParseException {
-        Date date = DateUtil.getDateParser(
-                "yyyy-MM-dd", 
TimeZone.getDefault()).parseDateTime("1970-01-01");
+        Date date = new Date(DateUtil.getDateTimeParser(
+                "yyyy-MM-dd", PDate.INSTANCE, 
TimeZone.getDefault().getID()).parseDateTime("1970-01-01"));
         assertEquals(Date.valueOf("1970-01-01"), date);
     }
 
     @Test
     public void testGetTimestampParser_DefaultTimeZone() throws ParseException 
{
-        Timestamp ts = new Timestamp(DateUtil.getTimestampParser("yyyy-MM-dd 
HH:mm:ss")
-                .parseDateTime("1970-01-01 00:00:00").getTime());
+        Timestamp ts = new Timestamp(DateUtil.getDateTimeParser("yyyy-MM-dd 
HH:mm:ss", PTimestamp.INSTANCE)
+                .parseDateTime("1970-01-01 00:00:00"));
         assertEquals(0, ts.getTime());
     }
 
     @Test
     public void testGetTimestampParser_CustomTimeZone() throws ParseException {
-        Timestamp ts = new Timestamp(DateUtil.getTimestampParser("yyyy-MM-dd 
HH:mm:ss", TimeZone.getTimeZone("GMT+1"))
-                .parseDateTime("1970-01-01 00:00:00").getTime());
+        Timestamp ts = new Timestamp(DateUtil.getDateTimeParser("yyyy-MM-dd 
HH:mm:ss", PTimestamp.INSTANCE, TimeZone.getTimeZone("GMT+1").getID())
+                .parseDateTime("1970-01-01 00:00:00"));
         assertEquals(-ONE_HOUR_IN_MILLIS, ts.getTime());
     }
 
     @Test
     public void testGetTimestampParser_LocalTimeZone() throws ParseException {
-        Timestamp ts = new Timestamp(DateUtil.getTimestampParser(
+        Timestamp ts = new Timestamp(DateUtil.getDateTimeParser(
                 "yyyy-MM-dd HH:mm:ss",
-                TimeZone.getDefault()).parseDateTime("1970-01-01 
00:00:00").getTime());
+                PTimestamp.INSTANCE, 
TimeZone.getDefault().getID()).parseDateTime("1970-01-01 00:00:00"));
         assertEquals(Timestamp.valueOf("1970-01-01 00:00:00"), ts);
     }
 
     @Test
     public void testGetTimeParser_DefaultTimeZone() throws ParseException {
-        Time time = new 
Time(DateUtil.getTimeParser("HH:mm:ss").parseDateTime("00:00:00").getTime());
+        Time time = new Time(DateUtil.getDateTimeParser("HH:mm:ss", 
PTime.INSTANCE).parseDateTime("00:00:00"));
         assertEquals(0, time.getTime());
     }
 
     @Test
     public void testGetTimeParser_CustomTimeZone() throws ParseException {
-        Time time = new Time(DateUtil.getTimeParser(
+        Time time = new Time(DateUtil.getDateTimeParser(
                 "HH:mm:ss",
-                
TimeZone.getTimeZone("GMT+1")).parseDateTime("00:00:00").getTime());
+                PTime.INSTANCE, 
TimeZone.getTimeZone("GMT+1").getID()).parseDateTime("00:00:00"));
         assertEquals(-ONE_HOUR_IN_MILLIS, time.getTime());
     }
 
     @Test
     public void testGetTimeParser_LocalTimeZone() throws ParseException {
-        Time time = new Time(DateUtil.getTimeParser(
-                "HH:mm:ss", 
TimeZone.getDefault()).parseDateTime("00:00:00").getTime());
+        Time time = new Time(DateUtil.getDateTimeParser(
+                "HH:mm:ss", PTime.INSTANCE, 
TimeZone.getDefault().getID()).parseDateTime("00:00:00"));
         assertEquals(Time.valueOf("00:00:00"), time);
     }
 

Reply via email to