You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by ji...@apache.org on 2014/05/22 03:33:38 UTC

[2/6] TAJO-825: Datetime type refactoring. (Hyoungjun Kim via jihoon)

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-common/src/test/java/org/apache/tajo/datum/TestTimestampDatum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/test/java/org/apache/tajo/datum/TestTimestampDatum.java b/tajo-common/src/test/java/org/apache/tajo/datum/TestTimestampDatum.java
index 6551077..818c296 100644
--- a/tajo-common/src/test/java/org/apache/tajo/datum/TestTimestampDatum.java
+++ b/tajo-common/src/test/java/org/apache/tajo/datum/TestTimestampDatum.java
@@ -19,105 +19,162 @@
 package org.apache.tajo.datum;
 
 import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.exception.InvalidCastException;
 import org.apache.tajo.json.CommonGsonHelper;
+import org.apache.tajo.util.datetime.DateTimeUtil;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import java.util.Calendar;
+import java.util.TimeZone;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
 public class TestTimestampDatum {
-
-  private static int timestamp;
+  private static long javatime;
+  private static int unixtime;
+  private static Calendar calendar;
 
   @BeforeClass
   public static void setUp() {
-    timestamp = (int) (System.currentTimeMillis() / 1000);
+    javatime = System.currentTimeMillis();
+    calendar = Calendar.getInstance(TajoConf.getCurrentTimeZone());
+    calendar.setTimeInMillis(javatime);
+    unixtime = (int) (javatime / 1000);
   }
 
 	@Test
 	public final void testType() {
-		Datum d = DatumFactory.createTimeStamp(timestamp);
-        assertEquals(Type.TIMESTAMP, d.type());
+		Datum d = DatumFactory.createTimestmpDatumWithUnixTime(unixtime);
+    assertEquals(Type.TIMESTAMP, d.type());
 	}
 
 	@Test(expected = InvalidCastException.class)
 	public final void testAsInt4() {
-    Datum d = DatumFactory.createTimeStamp(timestamp);
+    Datum d = DatumFactory.createTimestmpDatumWithUnixTime(unixtime);
     d.asInt4();
 	}
 
   @Test
 	public final void testAsInt8() {
-    Datum d = DatumFactory.createTimeStamp(timestamp);
-    long javaTime = timestamp * 1000l;
-    assertEquals(javaTime, d.asInt8());
+    Datum d = DatumFactory.createTimestmpDatumWithJavaMillis(unixtime * 1000);
+    long javaTime = unixtime * 1000;
+    assertEquals(DateTimeUtil.javaTimeToJulianTime(javaTime), d.asInt8());
 	}
 
   @Test(expected = InvalidCastException.class)
 	public final void testAsFloat4() {
-    Datum d = DatumFactory.createTimeStamp(timestamp);
+    Datum d = DatumFactory.createTimestmpDatumWithUnixTime(unixtime);
     d.asFloat4();
 	}
 
   @Test(expected = InvalidCastException.class)
 	public final void testAsFloat8() {
     int instance = 1386577582;
-    Datum d = DatumFactory.createTimeStamp(instance);
+    Datum d = DatumFactory.createTimestmpDatumWithUnixTime(instance);
     d.asFloat8();
 	}
 
 	@Test
 	public final void testAsText() {
-    Datum d = DatumFactory.createTimeStamp("1980-04-01 01:50:01");
-    Datum copy = DatumFactory.createTimeStamp(d.asChars());
+    Datum d = DatumFactory.createTimestamp("1980-04-01 01:50:01");
+    Datum copy = DatumFactory.createTimestamp(d.asChars());
     assertEquals(d, copy);
-	}
 
-  @Test
-  public final void testAsByteArray() {
-    TimestampDatum d = DatumFactory.createTimeStamp(timestamp);
-    TimestampDatum copy = new TimestampDatum(d.asByteArray());
+    d = DatumFactory.createTimestamp("1980-04-01 01:50:01.10");
+    copy = DatumFactory.createTimestamp(d.asChars());
     assertEquals(d, copy);
-  }
+	}
 
 	@Test
   public final void testSize() {
-    Datum d = DatumFactory.createTimeStamp(timestamp);
+    Datum d = DatumFactory.createTimestmpDatumWithUnixTime(unixtime);
     assertEquals(TimestampDatum.SIZE, d.asByteArray().length);
   }
 
   @Test
   public final void testAsTextBytes() {
-    Datum d = DatumFactory.createTimeStamp("1980-04-01 01:50:01");
+    Datum d = DatumFactory.createTimestamp("1980-04-01 01:50:01");
     assertArrayEquals(d.toString().getBytes(), d.asTextBytes());
 
-    d = DatumFactory.createTimeStamp("1980-04-01 01:50:01.578");
+    d = DatumFactory.createTimestamp("1980-04-01 01:50:01.578");
     assertArrayEquals(d.toString().getBytes(), d.asTextBytes());
   }
 
   @Test
   public final void testToJson() {
-    Datum d = DatumFactory.createTimeStamp(timestamp);
+    Datum d = DatumFactory.createTimestmpDatumWithUnixTime(unixtime);
     Datum copy = CommonGsonHelper.fromJson(d.toJson(), Datum.class);
     assertEquals(d, copy);
   }
 
   @Test
-  public final void testGetFields() {
-    TimestampDatum d = DatumFactory.createTimeStamp("1980-04-01 01:50:01");
-    assertEquals(1980, d.getYear());
-    assertEquals(4, d.getMonthOfYear());
-    assertEquals(1, d.getDayOfMonth());
-    assertEquals(1, d.getHourOfDay());
-    assertEquals(50, d.getMinuteOfHour());
-    assertEquals(01, d.getSecondOfMinute());
+  public final void testTimeZone() {
+    TimestampDatum datum = new TimestampDatum(DateTimeUtil.toJulianTimestamp(2014, 5, 1, 15, 20, 30, 0));
+    assertEquals("2014-05-01 15:20:30", datum.asChars());
+    assertEquals("2014-05-02 00:20:30+09", datum.asChars(TimeZone.getTimeZone("GMT+9"), true));
+  }
+
+  @Test
+  public final void testTimestampConstructor() {
+    TimestampDatum datum = new TimestampDatum(DateTimeUtil.toJulianTimestamp(2014, 5, 1, 10, 20, 30, 0));
+    assertEquals(2014, datum.getYear());
+    assertEquals(5, datum.getMonthOfYear());
+    assertEquals(1, datum.getDayOfMonth());
+    assertEquals(10, datum.getHourOfDay());
+    assertEquals(20, datum.getMinuteOfHour());
+    assertEquals(30, datum.getSecondOfMinute());
+
+    TimestampDatum datum2 = DatumFactory.createTimestamp("2014-05-01 10:20:30");
+    assertEquals(datum2, datum);
+
+    datum = DatumFactory.createTimestamp("1980-04-01 01:50:01.123");
+    assertEquals(1980, datum.getYear());
+    assertEquals(4, datum.getMonthOfYear());
+    assertEquals(1, datum.getDayOfMonth());
+    assertEquals(1, datum.getHourOfDay());
+    assertEquals(50, datum.getMinuteOfHour());
+    assertEquals(1, datum.getSecondOfMinute());
+    assertEquals(123, datum.getMillisOfSecond());
+
+    datum = new TimestampDatum(DateTimeUtil.toJulianTimestamp(1014, 5, 1, 10, 20, 30, 0));
+    assertEquals(1014, datum.getYear());
+    assertEquals(5, datum.getMonthOfYear());
+    assertEquals(1, datum.getDayOfMonth());
+    assertEquals(10, datum.getHourOfDay());
+    assertEquals(20, datum.getMinuteOfHour());
+    assertEquals(30, datum.getSecondOfMinute());
+
+    datum2 = DatumFactory.createTimestamp("1014-05-01 10:20:30");
+    assertEquals(datum2, datum);
+
+    for (int i = 0; i < 100; i++) {
+      Calendar cal = Calendar.getInstance();
+      long jTime = System.currentTimeMillis();
+      int uTime = (int)(jTime / 1000);
+      cal.setTimeInMillis(jTime);
+
+      long julianTimestamp = DateTimeUtil.javaTimeToJulianTime(jTime);
+      assertEquals(uTime, DateTimeUtil.julianTimeToEpoch(julianTimestamp));
+      assertEquals(jTime, DateTimeUtil.julianTimeToJavaTime(julianTimestamp));
+
+      TimestampDatum datum3 = DatumFactory.createTimestmpDatumWithJavaMillis(jTime);
+      assertEquals(cal.get(Calendar.YEAR), datum3.getYear());
+      assertEquals(cal.get(Calendar.MONTH) + 1, datum3.getMonthOfYear());
+      assertEquals(cal.get(Calendar.DAY_OF_MONTH), datum3.getDayOfMonth());
+
+      datum3 = DatumFactory.createTimestmpDatumWithUnixTime(uTime);
+      assertEquals(cal.get(Calendar.YEAR), datum3.getYear());
+      assertEquals(cal.get(Calendar.MONTH) + 1, datum3.getMonthOfYear());
+      assertEquals(cal.get(Calendar.DAY_OF_MONTH), datum3.getDayOfMonth());
+    }
   }
 
   @Test
   public final void testNull() {
-   Datum d = DatumFactory.createTimeStamp(timestamp);
+   Datum d = DatumFactory.createTimestmpDatumWithUnixTime(unixtime);
    assertEquals(Boolean.FALSE,d.equals(DatumFactory.createNullDatum()));
    assertEquals(DatumFactory.createNullDatum(),d.equalsTo(DatumFactory.createNullDatum()));
    assertEquals(-1,d.compareTo(DatumFactory.createNullDatum()));

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-common/src/test/java/org/apache/tajo/util/TestDateTimeFormat.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/test/java/org/apache/tajo/util/TestDateTimeFormat.java b/tajo-common/src/test/java/org/apache/tajo/util/TestDateTimeFormat.java
new file mode 100644
index 0000000..0bfe708
--- /dev/null
+++ b/tajo-common/src/test/java/org/apache/tajo/util/TestDateTimeFormat.java
@@ -0,0 +1,158 @@
+/**
+ * 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.tajo.util;
+
+import org.apache.tajo.datum.TimestampDatum;
+import org.apache.tajo.util.datetime.DateTimeFormat;
+import org.apache.tajo.util.datetime.TimeMeta;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormatter;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class TestDateTimeFormat {
+  @Test
+  public void testToTimestamp() {
+    evalToTimestampAndAssert("1997-12-30 11:40:50.345", "YYYY-MM-DD HH24:MI:SS.MS", 1997, 12, 30, 11, 40, 50, 345);
+    evalToTimestampAndAssert("1997-12-30 11:40:50.345 PM", "YYYY-MM-DD HH24:MI:SS.MS PM", 1997, 12, 30, 23, 40, 50, 345);
+    evalToTimestampAndAssert("0097/Feb/16 --> 08:14:30", "YYYY/Mon/DD --> HH:MI:SS", 97, 2, 16, 8, 14, 30, 0);
+    evalToTimestampAndAssert("97/2/16 8:14:30", "FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS", 97, 2, 16, 8, 14, 30, 0);
+    evalToTimestampAndAssert("1985 September 12", "YYYY FMMonth DD", 1985, 9, 12, 0, 0, 0, 0);
+    evalToTimestampAndAssert("1,582nd VIII 21", "Y,YYYth FMRM DD", 1582, 8, 21, 0, 0, 0, 0);
+    evalToTimestampAndAssert("05121445482000", "MMDDHH24MISSYYYY", 2000, 5, 12, 14, 45, 48, 0);
+    evalToTimestampAndAssert("2000January09Sunday", "YYYYFMMonthDDFMDay", 2000, 1, 9, 0, 0, 0, 0);
+    evalToTimestampAndAssert("97/Feb/16", "YY/Mon/DD", 1997, 2, 16, 0, 0, 0, 0);
+    evalToTimestampAndAssert("19971116", "YYYYMMDD", 1997, 11, 16, 0, 0, 0, 0);
+    evalToTimestampAndAssert("20000-1116", "YYYY-MMDD", 20000, 11, 16, 0, 0, 0, 0);
+    evalToTimestampAndAssert("9-1116", "Y-MMDD", 2009, 11, 16, 0, 0, 0, 0);
+    evalToTimestampAndAssert("95-1116", "YY-MMDD", 1995, 11, 16, 0, 0, 0, 0);
+    evalToTimestampAndAssert("995-1116", "YYY-MMDD", 1995, 11, 16, 0, 0, 0, 0);
+    evalToTimestampAndAssert("2005426", "YYYYWWD", 2005, 10, 15, 0, 0, 0, 0);
+    evalToTimestampAndAssert("2005300", "YYYYDDD", 2005, 10, 27, 0, 0, 0, 0);
+    evalToTimestampAndAssert("2005527", "IYYYIWID", 2006, 1, 1, 0, 0, 0, 0);
+    evalToTimestampAndAssert("005527", "IYYIWID", 2006, 1, 1, 0, 0, 0, 0);
+    evalToTimestampAndAssert("05527", "IYIWID", 2006, 1, 1, 0, 0, 0, 0);
+    evalToTimestampAndAssert("5527", "IIWID", 2006, 1, 1, 0, 0, 0, 0);
+    evalToTimestampAndAssert("2005364", "IYYYIDDD", 2006, 1, 1, 0, 0, 0, 0);
+    evalToTimestampAndAssert("20050302", "YYYYMMDD", 2005, 3, 2, 0, 0, 0, 0);
+    evalToTimestampAndAssert("2005 03 02", "YYYYMMDD", 2005, 3, 2, 0, 0, 0, 0);
+    evalToTimestampAndAssert(" 2005 03 02", "YYYYMMDD", 2005, 3, 2, 0, 0, 0, 0);
+    evalToTimestampAndAssert("  20050302", "YYYYMMDD", 2005, 3, 2, 0, 0, 0, 0);
+
+    //In the case of using Format Cache
+    evalToTimestampAndAssert("1998-02-28 10:20:30.123 PM", "YYYY-MM-DD HH24:MI:SS.MS PM", 1998, 2, 28, 22, 20, 30, 123);
+
+
+    try {
+      evalToTimestampAndAssert("97/Feb/16", "YYMonDD", 1997, 2, 16, 0, 0, 0, 0);
+      fail("Should be throw exception");
+    } catch (Exception e) {
+      //Invalid value /Fe for Mon. The given value did not match any of the allowed values for this field.
+    }
+
+    try {
+      evalToTimestampAndAssert("2005527", "YYYYIWID", 2005, 5, 27, 0, 0, 0, 0);
+      fail("Should be throw exception");
+    } catch (Exception e) {
+      //Do not mix Gregorian and ISO week date conventions in a formatting template.
+    }
+    try {
+      evalToTimestampAndAssert("19971", "YYYYMMDD", 1997, 1, 1, 0, 0, 0, 0);
+      fail("Should be throw exception");
+    } catch (Exception e) {
+      //If your source string is not fixed-width, try using the "FM" modifier.
+    }
+
+    TimeMeta tm = DateTimeFormat.parseDateTime("10:09:37.5", "HH24:MI:SS.MS");
+    assertEquals(10, tm.hours);
+  }
+
+  @Test
+  public void testToChar() {
+    evalToCharAndAssert("1970-01-17 10:09:37", "YYYY-MM-DD HH24:MI:SS", "1970-01-17 10:09:37");
+    evalToCharAndAssert("1997-12-30 11:40:50.345", "YYYY-MM-DD HH24:MI:SS.MS", "1997-12-30 11:40:50.345");
+    evalToCharAndAssert("1997-12-30 11:40:50.345 PM", "YYYY-MM-DD HH24:MI:SS.MS PM", "1997-12-30 23:40:50.345 PM");
+    evalToCharAndAssert("0097/Feb/16 --> 08:14:30", "YYYY/Mon/DD --> HH:MI:SS", "0097/Feb/16 --> 08:14:30");
+    evalToCharAndAssert("97/2/16 8:14:30", "FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS", "97/2/16 8:14:30");
+    evalToCharAndAssert("1985 September 12", "YYYY FMMonth DD", "1985 September 12");
+    evalToCharAndAssert("1,582nd VIII 21", "Y,YYYth FMRM DD", "1,582nd VIII 21");
+    evalToCharAndAssert("05121445482000", "MMDDHH24MISSYYYY", "05121445482000");
+    evalToCharAndAssert("2000January09Sunday", "YYYYFMMonthDDFMDay", "2000January09Sunday");
+    evalToCharAndAssert("97/Feb/16", "YY/Mon/DD", "97/Feb/16");
+    evalToCharAndAssert("19971116", "YYYYMMDD", "19971116");
+    evalToCharAndAssert("20000-1116", "YYYY-MMDD", "20000-1116");
+    evalToCharAndAssert("9-1116", "Y-MMDD", "9-1116");
+    evalToCharAndAssert("95-1116", "YY-MMDD", "95-1116");
+    evalToCharAndAssert("995-1116", "YYY-MMDD", "995-1116");
+    evalToCharAndAssert("2005426", "YYYYWWD", "2005427");
+    evalToCharAndAssert("2005300", "YYYYDDD", "2005300");
+    evalToCharAndAssert("2005527", "IYYYIWID", "2005527");
+    evalToCharAndAssert("005527", "IYYIWID", "005527");
+    evalToCharAndAssert("05527", "IYIWID", "05527");
+    evalToCharAndAssert("5527", "IIWID", "5527");
+    evalToCharAndAssert("2005364", "IYYYIDDD", "2005364");
+    evalToCharAndAssert("20050302", "YYYYMMDD", "20050302");
+    evalToCharAndAssert("2005 03 02", "YYYYMMDD", "YYYY MM DD", "2005 03 02");
+    evalToCharAndAssert(" 2005 03 02", "YYYYMMDD", " YYYY MM DD", " 2005 03 02");
+    evalToCharAndAssert("  20050302", "YYYYMMDD", "  YYYYMMDD", "  20050302");
+  }
+
+  @Test
+  public void testPerformance() {
+    DateTimeFormatter jodaFormat = org.joda.time.format.DateTimeFormat.forPattern("YYYY-MM-DD HH:mm:ss.SSS");
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < 10000000; i++) {
+      DateTime dateTime = jodaFormat.parseDateTime("1997-12-30 11:40:50.345");
+    }
+    long endTime = System.currentTimeMillis();
+    System.out.println("total parse time with JodaTime:" + (endTime - startTime) + " ms");
+
+    startTime = System.currentTimeMillis();
+    for (int i = 0; i < 10000000; i++) {
+      TimestampDatum datum = DateTimeFormat.toTimestamp("1997-12-30 11:40:50.345", "YYYY-MM-DD HH24:MI:SS.MS");
+    }
+    endTime = System.currentTimeMillis();
+    System.out.println("total parse time with TajoDateTimeFormat:" + (endTime - startTime) + " ms");
+  }
+
+  private void evalToTimestampAndAssert(String dateTimeText, String formatText,
+                                        int year, int month, int day, int hour, int minute, int sec, int msec) {
+    TimestampDatum datum = DateTimeFormat.toTimestamp(dateTimeText, formatText);
+    assertEquals(year, datum.getYear());
+    assertEquals(month, datum.getMonthOfYear());
+    assertEquals(day, datum.getDayOfMonth());
+    assertEquals(hour, datum.getHourOfDay());
+    assertEquals(minute, datum.getMinuteOfHour());
+    assertEquals(sec, datum.getSecondOfMinute());
+    assertEquals(msec, datum.getMillisOfSecond());
+  }
+
+  private void evalToCharAndAssert(String dateTimeText, String toTimestampFormatText, String expected) {
+    evalToCharAndAssert(dateTimeText, toTimestampFormatText, toTimestampFormatText, expected);
+  }
+
+  private void evalToCharAndAssert(String dateTimeText,
+                                   String toTimestampFormatText, String toCharFormatText, String expected) {
+    TimestampDatum datum = DateTimeFormat.toTimestamp(dateTimeText, toTimestampFormatText);
+    String toCharResult = DateTimeFormat.to_char(datum.toTimeMeta(), toCharFormatText);
+    assertEquals(expected, toCharResult);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-common/src/test/java/org/apache/tajo/util/TestDateTimeUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/test/java/org/apache/tajo/util/TestDateTimeUtil.java b/tajo-common/src/test/java/org/apache/tajo/util/TestDateTimeUtil.java
new file mode 100644
index 0000000..e953d44
--- /dev/null
+++ b/tajo-common/src/test/java/org/apache/tajo/util/TestDateTimeUtil.java
@@ -0,0 +1,439 @@
+/**
+ * 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.tajo.util;
+
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.util.datetime.DateTimeConstants;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.apache.tajo.util.datetime.TimeMeta;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.junit.Test;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import static org.junit.Assert.*;
+
+public class TestDateTimeUtil {
+  private static final int TEST_YEAR = 2014;
+  private static final int TEST_MONTH_OF_YEAR = 4;
+  private static final int TEST_DAY_OF_MONTH = 18;
+  private static final int TEST_HOUR_OF_DAY = 0;
+  private static final int TEST_MINUTE_OF_HOUR = 15;
+  private static final int TEST_SECOND_OF_MINUTE = 25;
+  private static final DateTime TEST_DATETIME = new DateTime(TEST_YEAR, TEST_MONTH_OF_YEAR, TEST_DAY_OF_MONTH,
+      TEST_HOUR_OF_DAY, TEST_MINUTE_OF_HOUR, TEST_SECOND_OF_MINUTE, DateTimeZone.UTC);
+  private static final DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
+
+  @Test
+  public void testDecodeDateTime() {
+    // http://www.postgresql.org/docs/9.1/static/datatype-datetime.html
+    TimeMeta tm = DateTimeUtil.decodeDateTime("2014-01-07 14:12:54+09");
+    assertEquals(2014, tm.years);
+    assertEquals(1, tm.monthOfYear);
+    assertEquals(7, tm.dayOfMonth);
+    assertEquals(14, tm.hours);
+    assertEquals(12, tm.minutes);
+    assertEquals(54, tm.secs);
+    assertEquals(0, tm.fsecs);
+
+    tm = DateTimeUtil.decodeDateTime("1999-01-08 04:05:06.789");
+    assertEquals(1999, tm.years);
+    assertEquals(1, tm.monthOfYear);
+    assertEquals(8, tm.dayOfMonth);
+    assertEquals(4, tm.hours);
+    assertEquals(5, tm.minutes);
+    assertEquals(6, tm.secs);
+    assertEquals(7 * 100000 + 8 * 10000 + 9 * 1000, tm.fsecs);
+
+    TimeMeta tm2 = DateTimeUtil.decodeDateTime("January 8, 1999 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    try {
+      tm2 = DateTimeUtil.decodeDateTime("January 8, 99 04:05:06.789");
+      assertEquals(tm, tm2);
+      fail("error in YMD mode");
+    } catch (Exception e) {
+      //throws Exception in YMD mode
+      //BAD Format: day overflow:99
+    }
+
+    TajoConf.setDateOrder(DateTimeConstants.DATEORDER_MDY);
+    tm2 = DateTimeUtil.decodeDateTime("January 8, 99 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    TajoConf.setDateOrder(DateTimeConstants.DATEORDER_YMD);
+    tm2 = DateTimeUtil.decodeDateTime("1999/1/8 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    tm2 = DateTimeUtil.decodeDateTime("1999/01/08 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    //January 2, 2003 in MDY mode; February 1, 2003 in DMY mode; February 3, 2001 in YMD mode
+    tm2 = DateTimeUtil.decodeDateTime("01/02/03 04:05:06.789");
+    assertEquals(2001, tm2.years);
+    assertEquals(2, tm2.monthOfYear);
+    assertEquals(3, tm2.dayOfMonth);
+    assertEquals(4, tm2.hours);
+    assertEquals(5, tm2.minutes);
+    assertEquals(6, tm2.secs);
+    assertEquals(7 * 100000 + 8 * 10000 + 9 * 1000, tm2.fsecs);
+
+    TajoConf.setDateOrder(DateTimeConstants.DATEORDER_MDY);
+    tm2 = DateTimeUtil.decodeDateTime("01/02/03 04:05:06.789");
+    assertEquals(2003, tm2.years);
+    assertEquals(1, tm2.monthOfYear);
+    assertEquals(2, tm2.dayOfMonth);
+    assertEquals(4, tm2.hours);
+    assertEquals(5, tm2.minutes);
+    assertEquals(6, tm2.secs);
+    assertEquals(7 * 100000 + 8 * 10000 + 9 * 1000, tm2.fsecs);
+
+    TajoConf.setDateOrder(DateTimeConstants.DATEORDER_DMY);
+    tm2 = DateTimeUtil.decodeDateTime("01/02/03 04:05:06.789");
+    assertEquals(2003, tm2.years);
+    assertEquals(2, tm2.monthOfYear);
+    assertEquals(1, tm2.dayOfMonth);
+    assertEquals(4, tm2.hours);
+    assertEquals(5, tm2.minutes);
+    assertEquals(6, tm2.secs);
+    assertEquals(7 * 100000 + 8 * 10000 + 9 * 1000, tm2.fsecs);
+
+    TajoConf.setDateOrder(DateTimeConstants.DATEORDER_YMD);
+    tm2 = DateTimeUtil.decodeDateTime("1999-Jan-08 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    tm2 = DateTimeUtil.decodeDateTime("Jan-08-1999 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    tm2 = DateTimeUtil.decodeDateTime("08-Jan-1999 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    tm2 = DateTimeUtil.decodeDateTime("99-Jan-08 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    //January 8, except error in YMD mode
+    TajoConf.setDateOrder(DateTimeConstants.DATEORDER_MDY);
+    tm2 = DateTimeUtil.decodeDateTime("08-Jan-99 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    //January 8, except error in YMD mode
+    tm2 = DateTimeUtil.decodeDateTime("Jan-08-99 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    TajoConf.setDateOrder(DateTimeConstants.DATEORDER_YMD);
+    tm2 = DateTimeUtil.decodeDateTime("19990108 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    tm2 = DateTimeUtil.decodeDateTime("990108 04:05:06.789");
+    assertEquals(tm, tm2);
+
+    //year and day of year
+    tm2 = DateTimeUtil.decodeDateTime("1999.008");
+    assertEquals(1999, tm2.years);
+    assertEquals(1, tm2.monthOfYear);
+    assertEquals(8, tm2.dayOfMonth);
+
+    //BC
+    tm = DateTimeUtil.decodeDateTime("19990108 BC 04:05:06.789");
+    assertEquals(-1998, tm.years);
+    assertEquals(1, tm.monthOfYear);
+    assertEquals(8, tm.dayOfMonth);
+    assertEquals(4, tm.hours);
+    assertEquals(5, tm.minutes);
+    assertEquals(6, tm.secs);
+    assertEquals(7 * 100000 + 8 * 10000 + 9 * 1000, tm.fsecs);
+
+    //PM
+    tm = DateTimeUtil.decodeDateTime("2013-04-25 10:20:30.4 PM");
+    assertEquals(2013, tm.years);
+    assertEquals(4, tm.monthOfYear);
+    assertEquals(25, tm.dayOfMonth);
+    assertEquals(22, tm.hours);
+    assertEquals(20, tm.minutes);
+    assertEquals(30, tm.secs);
+    assertEquals(4 * 100000, tm.fsecs);
+
+    // date only
+    tm = DateTimeUtil.decodeDateTime("1980-04-01");
+    assertEquals(1980, tm.years);
+    assertEquals(4, tm.monthOfYear);
+    assertEquals(1, tm.dayOfMonth);
+  }
+
+  @Test
+  public void testToJulianTimestamp() {
+    long julian = DateTimeUtil.toJulianTimestamp("2013-04-25");
+    assertEquals(julian, DateTimeUtil.toJulianTimestamp("2013-4-25"));
+    assertEquals(julian, DateTimeUtil.toJulianTimestamp("2013.4.25"));
+  }
+
+  @Test
+  public void testTimestampToJavaOrUnix() {
+    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+    long javaTime = System.currentTimeMillis();
+    cal.setTimeInMillis(javaTime);
+
+    long julianTimestamp = DateTimeUtil.javaTimeToJulianTime(cal.getTimeInMillis());
+
+    assertEquals(javaTime, DateTimeUtil.julianTimeToJavaTime(julianTimestamp));
+    assertEquals(javaTime/1000, DateTimeUtil.julianTimeToEpoch(julianTimestamp));
+  }
+
+  @Test
+  public void testLeapYear() {
+    assertTrue(DateTimeUtil.isLeapYear(2000));
+    assertTrue(DateTimeUtil.isLeapYear(2004));
+    assertTrue(DateTimeUtil.isLeapYear(1600));
+    assertFalse(DateTimeUtil.isLeapYear(1900));
+    assertFalse(DateTimeUtil.isLeapYear(2005));
+  }
+
+  @Test
+  public void testAddMonthsToTimeMeta() {
+    // Leap year
+    String dateTimeStr = "2000-01-29 23:11:50.123";
+    TimeMeta tm = DateTimeUtil.decodeDateTime(dateTimeStr);
+    tm.plusMonths(1);
+    assertEquals("2000-02-29 23:11:50.123", tm.toString());
+
+    // Non leap year
+    dateTimeStr = "1999-01-29 23:11:50.123";
+    tm = DateTimeUtil.decodeDateTime(dateTimeStr);
+    tm.plusMonths(1);
+    assertEquals("1999-02-28 23:11:50.123", tm.toString());
+
+    // changing year
+    dateTimeStr = "2013-09-30 23:11:50.123";
+    tm = DateTimeUtil.decodeDateTime(dateTimeStr);
+    tm.plusMonths(5);
+    assertEquals("2014-02-28 23:11:50.123", tm.toString());
+
+    // minus value
+    dateTimeStr = "2013-03-30 23:11:50.123";
+    tm = DateTimeUtil.decodeDateTime(dateTimeStr);
+    tm.plusMonths(-5);
+    assertEquals("2012-10-30 23:11:50.123", tm.toString());
+  }
+
+  @Test
+  public void testAddDaysToTimeMeta() {
+    // Leap year
+    String dateTimeStr = "2000-02-29 23:11:50.123";
+    TimeMeta tm = DateTimeUtil.decodeDateTime(dateTimeStr);
+    tm.plusDays(1);
+    assertEquals("2000-03-01 23:11:50.123", tm.toString());
+
+    // Non leap year
+    dateTimeStr = "1999-01-29 23:11:50.123";
+    tm = DateTimeUtil.decodeDateTime(dateTimeStr);
+    tm.plusDays(1);
+    assertEquals("1999-01-30 23:11:50.123", tm.toString());
+
+    // changing year
+    dateTimeStr = "2013-12-25 23:11:50.123";
+    tm = DateTimeUtil.decodeDateTime(dateTimeStr);
+    tm.plusDays(7);
+    assertEquals("2014-01-01 23:11:50.123", tm.toString());
+
+    // minus value
+    dateTimeStr = "2000-03-05 23:11:50.123";
+    tm = DateTimeUtil.decodeDateTime(dateTimeStr);
+    tm.plusDays(-10);
+    assertEquals("2000-02-24 23:11:50.123", tm.toString());
+  }
+
+  @Test
+  public void testEncodeDateTime() throws Exception {
+    //DateTimeUtil.encodeDateTime()
+
+  }
+
+  @Test
+  public void testAppendSeconds() throws Exception {
+    String[] fractions = new String[]{".999999", ".99999", ".9999", ".999", ".99", ".9", ""};
+
+    for (int i = 0; i < fractions.length; i++) {
+      StringBuilder sb = new StringBuilder("13:52:");
+      DateTimeUtil.appendSecondsToEncodeOutput(sb, 23, 999999, 6 - i, false);
+      assertEquals("13:52:23" + fractions[i], sb.toString());
+    }
+
+    fractions = new String[]{".1", ".01", ".001", ".0001", ".00001", ".000001"};
+    for (int i = 0; i < fractions.length; i++) {
+      StringBuilder sb = new StringBuilder("13:52:");
+      DateTimeUtil.appendSecondsToEncodeOutput(sb, 23, (int)Math.pow(10, (5 - i)), 6, false);
+      assertEquals("13:52:23" + fractions[i], sb.toString());
+    }
+  }
+
+  @Test
+  public void testTrimTrailingZeros() throws Exception {
+    StringBuilder sb1 = new StringBuilder("1.1200");
+    DateTimeUtil.trimTrailingZeros(sb1);
+    assertEquals("1.12", sb1.toString());
+
+    StringBuilder sb2 = new StringBuilder("1.12000120");
+    DateTimeUtil.trimTrailingZeros(sb2);
+    assertEquals("1.1200012", sb2.toString());
+
+    StringBuilder sb3 = new StringBuilder(".12000120");
+    DateTimeUtil.trimTrailingZeros(sb3);
+    assertEquals(".1200012", sb3.toString());
+  }
+
+  @Test
+  public void testTimeMeta() {
+    TimeMeta tm = DateTimeUtil.decodeDateTime("2014-12-31");
+    assertEquals(365, tm.getDayOfYear());
+
+    tm = DateTimeUtil.decodeDateTime("2000-03-01");
+    assertEquals(61, tm.getDayOfYear());
+
+    tm = DateTimeUtil.decodeDateTime("2014-01-01");
+    assertEquals(3, tm.getDayOfWeek());
+    assertEquals(1, tm.getWeekOfYear());
+    assertEquals(21, tm.getCenturyOfEra());
+
+    tm = DateTimeUtil.decodeDateTime("2000-03-01");
+    assertEquals(3, tm.getDayOfWeek());
+    assertEquals(9, tm.getWeekOfYear());
+    assertEquals(20, tm.getCenturyOfEra());
+
+    tm = DateTimeUtil.decodeDateTime("1752-09-14");
+    assertEquals(4, tm.getDayOfWeek());
+    assertEquals(37, tm.getWeekOfYear());
+    assertEquals(18, tm.getCenturyOfEra());
+
+    tm = DateTimeUtil.decodeDateTime("1752-09-02");
+    assertEquals(6, tm.getDayOfWeek());
+    assertEquals(35, tm.getWeekOfYear());
+    assertEquals(18, tm.getCenturyOfEra());
+
+    tm = DateTimeUtil.decodeDateTime("1200-04-01");
+    assertEquals(6, tm.getDayOfWeek());
+    assertEquals(13, tm.getWeekOfYear());
+    assertEquals(12, tm.getCenturyOfEra());
+
+    tm = DateTimeUtil.decodeDateTime("400-04-20");
+    assertEquals(4, tm.getDayOfWeek());
+    assertEquals(16, tm.getWeekOfYear());
+    assertEquals(4, tm.getCenturyOfEra());
+
+    tm = DateTimeUtil.decodeDateTime("310-12-31");
+    assertEquals(6, tm.getDayOfWeek());
+    assertEquals(52, tm.getWeekOfYear());
+    assertEquals(4, tm.getCenturyOfEra());
+
+    tm = DateTimeUtil.decodeDateTime("0080-02-29");
+    assertEquals(4, tm.getDayOfWeek());
+    assertEquals(9, tm.getWeekOfYear());
+    assertEquals(1, tm.getCenturyOfEra());
+
+    tm = DateTimeUtil.decodeDateTime("400-03-01 BC");
+    assertEquals(4, tm.getDayOfWeek());
+    assertEquals(9, tm.getWeekOfYear());
+    assertEquals(-4, tm.getCenturyOfEra());
+  }
+
+  @Test
+  public void testStrtoi() {
+    StringBuilder sb = new StringBuilder();
+    int intVal = 12345;
+    String textVal = "test";
+
+    int value = DateTimeUtil.strtoi(intVal + textVal, 0, sb);
+    assertEquals(intVal, value);
+    assertEquals(textVal, sb.toString());
+
+    textVal = "";
+
+    value = DateTimeUtil.strtoi(intVal + textVal, 0, sb);
+    assertEquals(intVal, value);
+    assertEquals(textVal, sb.toString());
+  }
+
+  @Test
+  public void testGetCenturyOfEra() {
+    assertEquals(1, DateTimeUtil.getCenturyOfEra(1));
+    assertEquals(1, DateTimeUtil.getCenturyOfEra(100));
+    assertEquals(2, DateTimeUtil.getCenturyOfEra(101));
+    assertEquals(10, DateTimeUtil.getCenturyOfEra(1000));
+    assertEquals(20, DateTimeUtil.getCenturyOfEra(1998));
+    assertEquals(20, DateTimeUtil.getCenturyOfEra(1999));
+    assertEquals(20, DateTimeUtil.getCenturyOfEra(2000));
+    assertEquals(21, DateTimeUtil.getCenturyOfEra(2001));
+    assertEquals(21, DateTimeUtil.getCenturyOfEra(2100));
+    assertEquals(22, DateTimeUtil.getCenturyOfEra(2101));
+
+    assertEquals(-6, DateTimeUtil.getCenturyOfEra(-600));
+    assertEquals(-6, DateTimeUtil.getCenturyOfEra(-501));
+    assertEquals(-5, DateTimeUtil.getCenturyOfEra(-500));
+    assertEquals(-5, DateTimeUtil.getCenturyOfEra(-455));
+    assertEquals(-1, DateTimeUtil.getCenturyOfEra(-1));
+  }
+
+  @Test
+  public void testGetTimeZoneDisplayTime() {
+    assertEquals("", DateTimeUtil.getTimeZoneDisplayTime(TimeZone.getTimeZone("GMT")));
+    assertEquals("+09", DateTimeUtil.getTimeZoneDisplayTime(TimeZone.getTimeZone("GMT+9")));
+    assertEquals("+09:10", DateTimeUtil.getTimeZoneDisplayTime(TimeZone.getTimeZone("GMT+9:10")));
+    assertEquals("-09", DateTimeUtil.getTimeZoneDisplayTime(TimeZone.getTimeZone("GMT-9")));
+    assertEquals("-09:10", DateTimeUtil.getTimeZoneDisplayTime(TimeZone.getTimeZone("GMT-9:10")));
+  }
+
+  @Test
+  public void testGetYear() {
+    assertEquals(DateTime.parse("2014-01-01 00:00:00", fmt.withZoneUTC()).getMillis() * 1000,
+        DateTimeUtil.getYear(TEST_DATETIME));
+  }
+
+  @Test
+  public void testGetMonth() {
+    assertEquals(DateTime.parse("2014-04-01 00:00:00", fmt.withZoneUTC()).getMillis() * 1000,
+        DateTimeUtil.getMonth(TEST_DATETIME));
+  }
+
+  @Test
+  public void testGetDay() {
+    assertEquals(DateTime.parse("2014-04-18 00:00:00", fmt.withZoneUTC()).getMillis() * 1000,
+        DateTimeUtil.getDay(TEST_DATETIME));
+  }
+
+  @Test
+  public void testGetHour() {
+    assertEquals(DateTime.parse("2014-04-18 00:00:00",fmt.withZoneUTC()).getMillis() * 1000,
+        DateTimeUtil.getHour(TEST_DATETIME));
+  }
+
+  @Test
+  public void testGetMinute() {
+    assertEquals(DateTime.parse("2014-04-18 00:15:00",fmt.withZoneUTC()).getMillis() * 1000,
+        DateTimeUtil.getMinute(TEST_DATETIME));
+  }
+
+  @Test
+  public void testGetSecond() {
+    assertEquals(DateTime.parse("2014-04-18 00:15:25",fmt.withZoneUTC()).getMillis() * 1000,
+        DateTimeUtil.getSecond(TEST_DATETIME));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-common/src/test/java/org/apache/tajo/util/TestTimeStampUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/test/java/org/apache/tajo/util/TestTimeStampUtil.java b/tajo-common/src/test/java/org/apache/tajo/util/TestTimeStampUtil.java
deleted file mode 100644
index 353063d..0000000
--- a/tajo-common/src/test/java/org/apache/tajo/util/TestTimeStampUtil.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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.tajo.util;
-
-import org.joda.time.DateTimeZone;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-import org.joda.time.DateTime;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class TestTimeStampUtil {
-  private static final int TEST_YEAR = 2014;
-  private static final int TEST_MONTH_OF_YEAR = 4;
-  private static final int TEST_DAY_OF_MONTH = 18;
-  private static final int TEST_HOUR_OF_DAY = 0;
-  private static final int TEST_MINUTE_OF_HOUR = 15;
-  private static final int TEST_SECOND_OF_MINUTE = 25;
-  private static final DateTime TEST_DATETIME = new DateTime(TEST_YEAR, TEST_MONTH_OF_YEAR, TEST_DAY_OF_MONTH,
-      TEST_HOUR_OF_DAY, TEST_MINUTE_OF_HOUR, TEST_SECOND_OF_MINUTE, DateTimeZone.UTC);
-  private static final DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
-
-  @Test
-  public void testGetYear() {
-    assertEquals(DateTime.parse("2014-01-01 00:00:00", fmt.withZoneUTC()).getMillis() * 1000,
-        TimeStampUtil.getYear(TEST_DATETIME));
-  }
-
-  @Test
-  public void testGetMonth() {
-    assertEquals(DateTime.parse("2014-04-01 00:00:00", fmt.withZoneUTC()).getMillis() * 1000,
-        TimeStampUtil.getMonth(TEST_DATETIME));
-  }
-
-  @Test
-  public void testGetDay() {
-    assertEquals(DateTime.parse("2014-04-18 00:00:00", fmt.withZoneUTC()).getMillis() * 1000,
-        TimeStampUtil.getDay(TEST_DATETIME));
-  }
-
-  @Test
-  public void testGetHour() {
-    assertEquals(DateTime.parse("2014-04-18 00:00:00",fmt.withZoneUTC()).getMillis() * 1000,
-        TimeStampUtil.getHour(TEST_DATETIME));
-  }
-
-  @Test
-  public void testGetMinute() {
-    assertEquals(DateTime.parse("2014-04-18 00:15:00",fmt.withZoneUTC()).getMillis() * 1000,
-        TimeStampUtil.getMinute(TEST_DATETIME));
-  }
-
-  @Test
-  public void testGetSecond() {
-    assertEquals(DateTime.parse("2014-04-18 00:15:25",fmt.withZoneUTC()).getMillis() * 1000,
-        TimeStampUtil.getSecond(TEST_DATETIME));
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromDate.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromDate.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromDate.java
index a010a7d..288fbe1 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromDate.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromDate.java
@@ -49,12 +49,12 @@ public class DatePartFromDate extends GeneralFunction {
   @Override
   public Datum eval(Tuple params) {
     Datum target = params.get(0);
-    DateDatum date = null;
 
     if(target instanceof NullDatum || params.get(1) instanceof NullDatum) {
       return NullDatum.get();
     }
 
+    DateDatum date;
     if(params.get(1) instanceof DateDatum) {
       date = (DateDatum)(params.get(1));
     } else {
@@ -124,8 +124,7 @@ public class DatePartFromDate extends GeneralFunction {
   private class DowExtractorFromDate implements DatePartExtractorFromDate {
     @Override
     public Datum extract(DateDatum date) {
-      Integer tdow = date.getDayOfWeek();
-      return DatumFactory.createFloat8((double) ((tdow == 7) ? 0 : tdow));
+      return DatumFactory.createFloat8((double) date.getDayOfWeek());
     }
   }
 
@@ -139,7 +138,7 @@ public class DatePartFromDate extends GeneralFunction {
   private class ISODowExtractorFromDate implements DatePartExtractorFromDate {
     @Override
     public Datum extract(DateDatum date) {
-      return DatumFactory.createFloat8((double) date.getDayOfWeek());
+      return DatumFactory.createFloat8((double) date.getISODayOfWeek());
     }
   }
 
@@ -174,7 +173,7 @@ public class DatePartFromDate extends GeneralFunction {
   private class WeekExtractorFromDate implements DatePartExtractorFromDate {
     @Override
     public Datum extract(DateDatum date) {
-      return DatumFactory.createFloat8((double) date.getWeekOfWeekyear());
+      return DatumFactory.createFloat8((double) date.getWeekOfYear());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTime.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTime.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTime.java
index 28e14fb..b3184e3 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTime.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTime.java
@@ -20,13 +20,20 @@ package org.apache.tajo.engine.function.datetime;
 
 import org.apache.tajo.catalog.Column;
 import org.apache.tajo.common.TajoDataTypes;
-import org.apache.tajo.datum.*;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.datum.TimeDatum;
 import org.apache.tajo.engine.function.GeneralFunction;
 import org.apache.tajo.engine.function.annotation.Description;
 import org.apache.tajo.engine.function.annotation.ParamTypes;
 import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.util.datetime.DateTimeConstants;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.apache.tajo.util.datetime.TimeMeta;
 
-import static org.apache.tajo.common.TajoDataTypes.Type.*;
+import static org.apache.tajo.common.TajoDataTypes.Type.FLOAT8;
+import static org.apache.tajo.common.TajoDataTypes.Type.TEXT;
 
 @Description(
     functionName = "date_part",
@@ -85,55 +92,57 @@ public class DatePartFromTime extends GeneralFunction {
       }
     }
 
-    return extractor.extract(time);
+    TimeMeta tm = time.toTimeMeta();
+    DateTimeUtil.toUserTimezone(tm);
+    return extractor.extract(tm);
   }
 
   private interface DatePartExtractorFromTime {
-    public Datum extract(TimeDatum time);
+    public Datum extract(TimeMeta tm);
   }
 
   private class HourExtractorFromTime implements DatePartExtractorFromTime {
     @Override
-    public Datum extract(TimeDatum time) {
-      return DatumFactory.createFloat8((double) time.getHourOfDay());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.hours);
     }
   }
 
   private class MicrosecondsExtractorFromTime implements DatePartExtractorFromTime {
     @Override
-    public Datum extract(TimeDatum time) {
-      return DatumFactory.createFloat8((double) (time.getSecondOfMinute() * 1000000 + time.getMillisOfSecond() * 1000));
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) (tm.secs * 1000000 + tm.fsecs));
     }
   }
 
   private class MillisecondsExtractorFromTime implements DatePartExtractorFromTime {
     @Override
-    public Datum extract(TimeDatum time) {
-      return DatumFactory.createFloat8((double) (time.getSecondOfMinute() * 1000 + time.getMillisOfSecond()));
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) (tm.secs * 1000 + tm.fsecs / 1000.0));
     }
   }
 
   private class MinuteExtractorFromTime implements DatePartExtractorFromTime {
     @Override
-    public Datum extract(TimeDatum time) {
-      return DatumFactory.createFloat8((double) time.getMinuteOfHour());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.minutes);
     }
   }
 
   private class SecondExtractorFromTime implements DatePartExtractorFromTime {
     @Override
-    public Datum extract(TimeDatum time) {
-      if (time.getMillisOfSecond() != 0) {
-        return DatumFactory.createFloat8(time.getSecondOfMinute() + (((double) time.getMillisOfSecond()) / 1000));
+    public Datum extract(TimeMeta tm) {
+      if (tm.fsecs != 0) {
+        return DatumFactory.createFloat8(tm.secs + (((double) tm.fsecs) / (double)DateTimeConstants.USECS_PER_SEC));
       } else {
-        return DatumFactory.createFloat8((double) time.getSecondOfMinute());
+        return DatumFactory.createFloat8((double) tm.secs);
       }
     }
   }
 
   private class NullExtractorFromTime implements DatePartExtractorFromTime {
     @Override
-    public Datum extract(TimeDatum time) {
+    public Datum extract(TimeMeta tm) {
       return NullDatum.get();
     }
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTimestamp.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTimestamp.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTimestamp.java
index 3b46929..98900ef 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTimestamp.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DatePartFromTimestamp.java
@@ -25,6 +25,9 @@ import org.apache.tajo.engine.function.GeneralFunction;
 import org.apache.tajo.engine.function.annotation.Description;
 import org.apache.tajo.engine.function.annotation.ParamTypes;
 import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.util.datetime.DateTimeConstants;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.apache.tajo.util.datetime.TimeMeta;
 
 import static org.apache.tajo.common.TajoDataTypes.Type.*;
 
@@ -49,7 +52,7 @@ public class DatePartFromTimestamp extends GeneralFunction {
   @Override
   public Datum eval(Tuple params) {
     Datum target = params.get(0);
-    TimestampDatum timestamp = null;
+    TimestampDatum timestamp;
 
     if(target instanceof NullDatum || params.get(1) instanceof NullDatum) {
       return NullDatum.get();
@@ -111,147 +114,150 @@ public class DatePartFromTimestamp extends GeneralFunction {
       }
     }
 
-    return extractor.extract(timestamp);
+    TimeMeta tm = timestamp.toTimeMeta();
+    DateTimeUtil.toUserTimezone(tm);
+
+    return extractor.extract(tm);
   }
 
   private interface DatePartExtractorFromTimestamp {
-    public Datum extract(TimestampDatum timestamp);
+    public Datum extract(TimeMeta tm);
   }
 
   private class CenturyExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getCenturyOfEra());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.getCenturyOfEra());
     }
   } 
 
   private class DayExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getDayOfMonth());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.dayOfMonth);
     }
   }
 
   private class DecadeExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) (timestamp.getYear() / 10));
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) (tm.years / 10));
     }
   }
 
   private class DowExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      Integer tdow = timestamp.getDayOfWeek();
+    public Datum extract(TimeMeta tm) {
+      Integer tdow = tm.getDayOfWeek();
       return DatumFactory.createFloat8((double) ((tdow == 7) ? 0 : tdow));
     }
   }
 
   private class DoyExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getDayOfYear());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double)tm.getDayOfYear());
     }
   }
 
   private class EpochExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getUnixTime());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double)DateTimeUtil.julianTimeToEpoch(DateTimeUtil.toJulianTimestamp(tm)));
     }
   }
 
   private class HourExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getHourOfDay());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.hours);
     }
   }
 
   private class ISODowExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getDayOfWeek());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.getISODayOfWeek());
     }
   }
 
   private class ISOYearExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getWeekyear());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.getWeekyear());
     }
   }
 
   private class MicrosecondsExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) (timestamp.getSecondOfMinute() * 1000000 + timestamp.getMillisOfSecond() * 1000));
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) (tm.secs * 1000000 + tm.fsecs));
     }
   }
 
   private class MillenniumExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) (((timestamp.getYear() - 1) / 1000) + 1));
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) (((tm.years - 1) / 1000) + 1));
     }
   }
 
   private class MillisecondsExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) (timestamp.getSecondOfMinute() * 1000 + timestamp.getMillisOfSecond()));
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) (tm.secs * 1000 + tm.fsecs / 1000.0));
     }
   }
 
   private class MinuteExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getMinuteOfHour());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.minutes);
     }
   }
 
   private class MonthExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getMonthOfYear());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.monthOfYear);
     }
   }
 
   private class QuarterExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) (((timestamp.getMonthOfYear() - 1) / 3) + 1));
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) (((tm.monthOfYear - 1) / 3) + 1));
     }
   }
 
   private class SecondExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      if (timestamp.getMillisOfSecond() != 0) {
-        return DatumFactory.createFloat8(timestamp.getSecondOfMinute() + (((double) timestamp.getMillisOfSecond()) / 1000));
+    public Datum extract(TimeMeta tm) {
+      if (tm.fsecs != 0) {
+        return DatumFactory.createFloat8(tm.secs + (((double) tm.fsecs) / (double) DateTimeConstants.USECS_PER_SEC));
       } else {
-        return DatumFactory.createFloat8((double) timestamp.getSecondOfMinute());
+        return DatumFactory.createFloat8((double) tm.secs);
       }
     }
   }
 
   private class WeekExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getWeekOfWeekyear());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.getWeekOfYear());
     }
   }
 
   private class YearExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
-      return DatumFactory.createFloat8((double) timestamp.getYear());
+    public Datum extract(TimeMeta tm) {
+      return DatumFactory.createFloat8((double) tm.years);
     }
   }
 
   private class NullExtractorFromTimestamp implements DatePartExtractorFromTimestamp {
     @Override
-    public Datum extract(TimestampDatum timestamp) {
+    public Datum extract(TimeMeta tm) {
       return NullDatum.get();
     }
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DateTimePartFromUnixTimeStamp.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DateTimePartFromUnixTimeStamp.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DateTimePartFromUnixTimeStamp.java
index 6aaded0..8705b06 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DateTimePartFromUnixTimeStamp.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/DateTimePartFromUnixTimeStamp.java
@@ -25,117 +25,117 @@ import org.apache.tajo.engine.function.GeneralFunction;
 import org.apache.tajo.engine.function.annotation.Description;
 import org.apache.tajo.engine.function.annotation.ParamTypes;
 import org.apache.tajo.storage.Tuple;
-import org.apache.tajo.util.TimeStampUtil;
+import org.apache.tajo.util.datetime.DateTimeUtil;
 import org.joda.time.DateTime;
 
 import static org.apache.tajo.common.TajoDataTypes.Type.*;
 
 
 @Description(
-        functionName = "utc_usec_to",
-        description = "Extract field from time",
-        example = "> SELECT utc_usec_to('day', 1274259481071200);\n"
-                + "1274227200000000",
-        returnType = TajoDataTypes.Type.INT8,
-        paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT8}),
-                @ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT8, TajoDataTypes.Type.INT4})}
+    functionName = "utc_usec_to",
+    description = "Extract field from time",
+    example = "> SELECT utc_usec_to('day', 1274259481071200);\n"
+        + "1274227200000000",
+    returnType = TajoDataTypes.Type.INT8,
+    paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT8}),
+        @ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT8, TajoDataTypes.Type.INT4})}
 )
-public class DateTimePartFromUnixTimeStamp extends GeneralFunction {
+public class DateTimePartFromUnixTimestamp extends GeneralFunction {
 
-    private DateTimePartExtractorFromUnixTime extractor = null;
-    private WeekPartExtractorFromUnixTime weekExtractor = null;
+  private DateTimePartExtractorFromUnixTime extractor = null;
+  private WeekPartExtractorFromUnixTime weekExtractor = null;
 
-    public DateTimePartFromUnixTimeStamp() {
-        super(new Column[]{
-                new Column("target", TEXT),
-                new Column("source", INT8),
-                new Column("dayOfWeek", INT4),
+  public DateTimePartFromUnixTimestamp() {
+    super(new Column[]{
+        new Column("target", TEXT),
+        new Column("source", INT8),
+        new Column("dayOfWeek", INT4),
 
-        });
-    }
+    });
+  }
 
-    @Override
-    public Datum eval(Tuple params) {
+  @Override
+  public Datum eval(Tuple params) {
 
-        Datum target = params.get(0);
-        DateTime dateTime;
-        Int4Datum dayOfWeek = null;
+    Datum target = params.get(0);
+    DateTime dateTime;
+    Int4Datum dayOfWeek = null;
 
-        if (target instanceof NullDatum || params.get(1) instanceof NullDatum) {
-            return NullDatum.get();
-        }
+    if (target instanceof NullDatum || params.get(1) instanceof NullDatum) {
+      return NullDatum.get();
+    }
 
-        if (params.get(1) instanceof Int8Datum) {
-            dateTime = TimeStampUtil.getUTCDateTime((Int8Datum) (params.get(1)));
-        } else {
-            return NullDatum.get();
-        }
+    if (params.get(1) instanceof Int8Datum) {
+      dateTime = DateTimeUtil.getUTCDateTime((Int8Datum) (params.get(1)));
+    } else {
+      return NullDatum.get();
+    }
 
 
-        if ( null == extractor || null == weekExtractor) {
-
-            String extractType = target.asChars().toLowerCase();
-
-            if (extractType.equals("day")) {
-                extractor = new DayExtractorFromTime();
-            } else if (extractType.equals("hour")) {
-                extractor = new HourExtractorFromTime();
-            } else if (extractType.equals("month")) {
-                extractor = new MonthExtractorFromTime();
-            } else if (extractType.equals("year")) {
-                extractor = new YearExtractorFromTime();
-            } else if (extractType.equals("week")) {
-                if (params.get(2) instanceof NullDatum) {
-                    return NullDatum.get();
-                }
-                dayOfWeek = (Int4Datum) params.get(2);
-                weekExtractor = new WeekExtractorFromTime();
-            }
-        }
+    if ( null == extractor || null == weekExtractor) {
 
-        return null != weekExtractor ? weekExtractor.extract(dateTime, dayOfWeek.asInt4()) : extractor.extract(dateTime);
-    }
+      String extractType = target.asChars().toLowerCase();
 
-    private interface DateTimePartExtractorFromUnixTime {
-        public Datum extract(DateTime dateTime);
+      if (extractType.equals("day")) {
+        extractor = new DayExtractorFromTime();
+      } else if (extractType.equals("hour")) {
+        extractor = new HourExtractorFromTime();
+      } else if (extractType.equals("month")) {
+        extractor = new MonthExtractorFromTime();
+      } else if (extractType.equals("year")) {
+        extractor = new YearExtractorFromTime();
+      } else if (extractType.equals("week")) {
+        if (params.get(2) instanceof NullDatum) {
+          return NullDatum.get();
+        }
+        dayOfWeek = (Int4Datum) params.get(2);
+        weekExtractor = new WeekExtractorFromTime();
+      }
     }
 
-    private interface WeekPartExtractorFromUnixTime {
-        public Datum extract(DateTime dateTime, int week);
-    }
+    return null != weekExtractor ? weekExtractor.extract(dateTime, dayOfWeek.asInt4()) : extractor.extract(dateTime);
+  }
 
-    private class DayExtractorFromTime implements DateTimePartExtractorFromUnixTime {
-        @Override
-        public Datum extract(DateTime dateTime) {
-            return DatumFactory.createInt8(TimeStampUtil.getDay(dateTime));
-        }
+  private interface DateTimePartExtractorFromUnixTime {
+    public Datum extract(DateTime dateTime);
+  }
+
+  private interface WeekPartExtractorFromUnixTime {
+    public Datum extract(DateTime dateTime, int week);
+  }
+
+  private class DayExtractorFromTime implements DateTimePartExtractorFromUnixTime {
+    @Override
+    public Datum extract(DateTime dateTime) {
+      return DatumFactory.createInt8(DateTimeUtil.getDay(dateTime));
     }
+  }
 
-    private class HourExtractorFromTime implements DateTimePartExtractorFromUnixTime {
-        @Override
-        public Datum extract(DateTime dateTime) {
-            return DatumFactory.createInt8(TimeStampUtil.getHour(dateTime));
-        }
+  private class HourExtractorFromTime implements DateTimePartExtractorFromUnixTime {
+    @Override
+    public Datum extract(DateTime dateTime) {
+      return DatumFactory.createInt8(DateTimeUtil.getHour(dateTime));
     }
+  }
 
-    private class MonthExtractorFromTime implements DateTimePartExtractorFromUnixTime {
-        @Override
-        public Datum extract(DateTime dateTime) {
-            return DatumFactory.createInt8(TimeStampUtil.getMonth(dateTime));
-        }
+  private class MonthExtractorFromTime implements DateTimePartExtractorFromUnixTime {
+    @Override
+    public Datum extract(DateTime dateTime) {
+      return DatumFactory.createInt8(DateTimeUtil.getMonth(dateTime));
     }
+  }
 
-    private class YearExtractorFromTime implements DateTimePartExtractorFromUnixTime {
-        @Override
-        public Datum extract(DateTime dateTime) {
-            return DatumFactory.createInt8(TimeStampUtil.getYear(dateTime));
-        }
+  private class YearExtractorFromTime implements DateTimePartExtractorFromUnixTime {
+    @Override
+    public Datum extract(DateTime dateTime) {
+      return DatumFactory.createInt8(DateTimeUtil.getYear(dateTime));
     }
+  }
 
-    private class WeekExtractorFromTime implements WeekPartExtractorFromUnixTime {
-        @Override
-        public Datum extract(DateTime dateTime , int week) {
-            return DatumFactory.createInt8(TimeStampUtil.getDayOfWeek(dateTime,week));
-        }
+  private class WeekExtractorFromTime implements WeekPartExtractorFromUnixTime {
+    @Override
+    public Datum extract(DateTime dateTime , int week) {
+      return DatumFactory.createInt8(DateTimeUtil.getDayOfWeek(dateTime,week));
     }
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToCharTimestamp.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToCharTimestamp.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToCharTimestamp.java
index 2a74ff5..4ad76c4 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToCharTimestamp.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToCharTimestamp.java
@@ -29,39 +29,33 @@ import org.apache.tajo.engine.function.GeneralFunction;
 import org.apache.tajo.engine.function.annotation.Description;
 import org.apache.tajo.engine.function.annotation.ParamTypes;
 import org.apache.tajo.storage.Tuple;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
+import org.apache.tajo.util.datetime.DateTimeFormat;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.apache.tajo.util.datetime.TimeMeta;
 
-import static org.apache.tajo.common.TajoDataTypes.Type.INT8;
 import static org.apache.tajo.common.TajoDataTypes.Type.TEXT;
+import static org.apache.tajo.common.TajoDataTypes.Type.TIMESTAMP;
 
 @Description(
   functionName = "to_char",
-  description = "Convert time stamp to string",
-  example = "> SELECT to_char(1389071652, 'yyyy-MM');\n"
+  description = "Convert time stamp to string. Format should be a SQL standard format string.",
+  example = "> SELECT to_char(TIMESTAMP '2014-01-17 10:09:37', 'YYYY-MM');\n"
           + "2014-01",
   returnType = TajoDataTypes.Type.TEXT,
   paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TIMESTAMP, TajoDataTypes.Type.TEXT})}
 )
 public class ToCharTimestamp extends GeneralFunction {
-  private boolean constantFormat;
-  private DateTimeFormatter formatter;
-
   public ToCharTimestamp() {
     super(new Column[] {
-        new Column("timestamp", INT8),
+        new Column("timestamp", TIMESTAMP),
         new Column("format", TEXT)
     });
   }
 
   @Override
   public void init(FunctionEval.ParamType[] paramTypes) {
-    if (paramTypes[1] == FunctionEval.ParamType.CONSTANT) {
-      constantFormat = true;
-    }
   }
 
-
   @Override
   public Datum eval(Tuple params) {
     if(params.isNull(0) || params.isNull(1)) {
@@ -69,11 +63,11 @@ public class ToCharTimestamp extends GeneralFunction {
     }
 
     TimestampDatum valueDatum = (TimestampDatum) params.get(0);
+    TimeMeta tm = valueDatum.toTimeMeta();
+    DateTimeUtil.toUserTimezone(tm);
+
     Datum pattern = params.get(1);
 
-    if (formatter == null || !constantFormat) {
-      formatter = DateTimeFormat.forPattern(pattern.asChars());
-    }
-    return DatumFactory.createText(valueDatum.toChars(formatter));
+    return DatumFactory.createText(DateTimeFormat.to_char(tm, pattern.asChars()));
   }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToDate.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToDate.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToDate.java
index ba6a020..09a4395 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToDate.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToDate.java
@@ -27,24 +27,19 @@ import org.apache.tajo.engine.function.GeneralFunction;
 import org.apache.tajo.engine.function.annotation.Description;
 import org.apache.tajo.engine.function.annotation.ParamTypes;
 import org.apache.tajo.storage.Tuple;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
+import org.apache.tajo.util.datetime.DateTimeFormat;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.apache.tajo.util.datetime.TimeMeta;
 
 @Description(
     functionName = "to_date",
-    description = "Convert string to date. Format should be a java format string.",
-    example = "> SELECT to_date('2014-01-01', 'yyyy-MM-dd');\n"
+    description = "Convert string to date. Format should be a SQL standard format string.",
+    example = "> SELECT to_date('2014-01-01', 'YYYY-MM-DD');\n"
         + "2014-01-01",
     returnType = TajoDataTypes.Type.DATE,
     paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.TEXT})}
 )
 public class ToDate extends GeneralFunction {
-  private static Map<String, DateTimeFormatter> formattercCache =
-      new ConcurrentHashMap<String, DateTimeFormatter>();
-
   public ToDate() {
     super(new Column[]{
         new Column("string", TajoDataTypes.Type.TEXT),
@@ -60,12 +55,8 @@ public class ToDate extends GeneralFunction {
     String value = params.get(0).asChars();
     String pattern = params.get(1).asChars();
 
-    DateTimeFormatter formatter = formattercCache.get(pattern);
-    if (formatter == null) {
-      formatter = DateTimeFormat.forPattern(pattern);
-      formattercCache.put(pattern, formatter);
-    }
+    TimeMeta tm = DateTimeFormat.parseDateTime(value, pattern);
 
-    return new DateDatum(formatter.parseDateTime(value).toLocalDate());
+    return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth));
   }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestamp.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestamp.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestamp.java
deleted file mode 100644
index 1cf6870..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestamp.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * 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.tajo.engine.function.datetime;
-
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.common.TajoDataTypes;
-import org.apache.tajo.datum.Datum;
-import org.apache.tajo.datum.DatumFactory;
-import org.apache.tajo.datum.NullDatum;
-import org.apache.tajo.engine.function.GeneralFunction;
-import org.apache.tajo.engine.function.annotation.Description;
-import org.apache.tajo.engine.function.annotation.ParamTypes;
-import org.apache.tajo.storage.Tuple;
-
-import static org.apache.tajo.common.TajoDataTypes.Type.INT4;
-
-@Description(
-  functionName = "to_timestamp",
-  description = "Convert UNIX epoch to time stamp",
-  example = "> SELECT to_timestamp(1389071574);\n"
-        + "2014-01-07 14:12:54",
-  returnType = TajoDataTypes.Type.TIMESTAMP,
-  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.INT4}),
-      @ParamTypes(paramTypes = {TajoDataTypes.Type.INT8})}
-)
-public class ToTimestamp extends GeneralFunction {
-  public ToTimestamp() {
-    super(new Column[] {new Column("timestamp", INT4)});
-  }
-
-  @Override
-  public Datum eval(Tuple params) {
-    Datum value = params.get(0);
-    if (value instanceof NullDatum) {
-      return NullDatum.get();
-    }
-    return DatumFactory.createTimeStamp(value.asInt4());
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestampInt.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestampInt.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestampInt.java
new file mode 100644
index 0000000..d14cfd6
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestampInt.java
@@ -0,0 +1,55 @@
+/**
+ * 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.tajo.engine.function.datetime;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.INT4;
+
+@Description(
+  functionName = "to_timestamp",
+  description = "Convert UNIX epoch to time stamp",
+  example = "> SELECT to_timestamp(1389071574);\n"
+        + "2014-01-07 14:12:54",
+  returnType = TajoDataTypes.Type.TIMESTAMP,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.INT4}),
+      @ParamTypes(paramTypes = {TajoDataTypes.Type.INT8})}
+)
+public class ToTimestampInt extends GeneralFunction {
+  public ToTimestampInt() {
+    super(new Column[] {new Column("timestamp", INT4)});
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum value = params.get(0);
+    if (value instanceof NullDatum) {
+      return NullDatum.get();
+    }
+    return DatumFactory.createTimestmpDatumWithUnixTime(value.asInt4());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestampText.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestampText.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestampText.java
new file mode 100644
index 0000000..f42a171
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToTimestampText.java
@@ -0,0 +1,62 @@
+/**
+ * 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.tajo.engine.function.datetime;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.*;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.util.datetime.DateTimeFormat;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.apache.tajo.util.datetime.TimeMeta;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.TEXT;
+
+@Description(
+    functionName = "to_timestamp",
+    description = "Convert string to time stamp",
+    detail = "Patterns for Date/Time Formatting: http://www.postgresql.org/docs/8.4/static/functions-formatting.html",
+    example = "> select to_timestamp('05 Dec 2000 15:12:02.020', 'DD Mon YYYY HH24:MI:SS.MS');\n"
+        + "2000-12-05 15:12:02.02",
+    returnType = TajoDataTypes.Type.TIMESTAMP,
+    paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.TEXT})}
+)
+public class ToTimestampText extends GeneralFunction {
+  public ToTimestampText() {
+    super(new Column[]{new Column("DateTimeText", TEXT), new Column("Pattern", TEXT)});
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    if(params.isNull(0) || params.isNull(1)) {
+      return NullDatum.get();
+    }
+
+    TextDatum dateTimeTextDatum = (TextDatum) params.get(0);
+    TextDatum patternDatum = (TextDatum) params.get(1);
+
+    TimeMeta tm = DateTimeFormat.parseDateTime(dateTimeTextDatum.asChars(), patternDatum.asChars());
+    DateTimeUtil.toUTCTimezone(tm);
+
+    return new TimestampDatum(DateTimeUtil.toJulianTimestamp(tm));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java
index e74fd70..ba80c25 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java
@@ -34,7 +34,8 @@ import org.apache.tajo.engine.planner.logical.NodeType;
 import org.apache.tajo.exception.InternalException;
 import org.apache.tajo.util.Pair;
 import org.apache.tajo.util.TUtil;
-import org.joda.time.DateTime;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.apache.tajo.util.datetime.TimeMeta;
 
 import java.util.Map;
 import java.util.Stack;
@@ -611,7 +612,7 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
     FunctionDesc countRows = catalog.getFunction("count", CatalogProtos.FunctionType.AGGREGATION,
         new DataType[] {});
     if (countRows == null) {
-      throw new NoSuchFunctionException(countRows.getSignature(), new DataType[]{});
+      throw new NoSuchFunctionException(expr.getSignature(), new DataType[]{});
     }
 
     try {
@@ -704,8 +705,16 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
   @Override
   public EvalNode visitDateLiteral(Context context, Stack<Expr> stack, DateLiteral expr) throws PlanningException {
     DateValue dateValue = expr.getDate();
-    int [] dates = dateToIntArray(dateValue.getYears(), dateValue.getMonths(), dateValue.getDays());
-    return new ConstEval(new DateDatum(dates[0], dates[1], dates[2]));
+    int[] dates = dateToIntArray(dateValue.getYears(), dateValue.getMonths(), dateValue.getDays());
+
+    TimeMeta tm = new TimeMeta();
+    tm.years = dates[0];
+    tm.monthOfYear = dates[1];
+    tm.dayOfMonth = dates[2];
+
+    DateTimeUtil.j2date(DateTimeUtil.date2j(dates[0], dates[1], dates[2]), tm);
+
+    return new ConstEval(new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)));
   }
 
   @Override
@@ -721,14 +730,20 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
         timeValue.getMinutes(),
         timeValue.getSeconds(),
         timeValue.getSecondsFraction());
-    DateTime dateTime;
+
+    long timestamp;
     if (timeValue.hasSecondsFraction()) {
-      dateTime = new DateTime(dates[0], dates[1], dates[2], times[0], times[1], times[2], times[3]);
+      timestamp = DateTimeUtil.toJulianTimestamp(dates[0], dates[1], dates[2], times[0], times[1], times[2],
+          times[3] * 1000);
     } else {
-      dateTime = new DateTime(dates[0], dates[1], dates[2], times[0], times[1], times[2]);
+      timestamp = DateTimeUtil.toJulianTimestamp(dates[0], dates[1], dates[2], times[0], times[1], times[2], 0);
     }
 
-    return new ConstEval(new TimestampDatum(dateTime));
+    TimeMeta tm = new TimeMeta();
+    DateTimeUtil.toJulianTimeMeta(timestamp, tm);
+    DateTimeUtil.toUTCTimezone(tm);
+
+    return new ConstEval(new TimestampDatum(DateTimeUtil.toJulianTimestamp(tm)));
   }
 
   @Override
@@ -744,13 +759,17 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
         timeValue.getSeconds(),
         timeValue.getSecondsFraction());
 
-    TimeDatum datum;
+    long time;
     if (timeValue.hasSecondsFraction()) {
-      datum = new TimeDatum(times[0], times[1], times[2], times[3]);
+      time = DateTimeUtil.toTime(times[0], times[1], times[2], times[3] * 1000);
     } else {
-      datum = new TimeDatum(times[0], times[1], times[2]);
+      time = DateTimeUtil.toTime(times[0], times[1], times[2], 0);
     }
-    return new ConstEval(datum);
+    TimeDatum timeDatum = new TimeDatum(time);
+    TimeMeta tm = timeDatum.toTimeMeta();
+    DateTimeUtil.toUTCTimezone(tm);
+
+    return new ConstEval(new TimeDatum(DateTimeUtil.toTime(tm)));
   }
 
   public static int [] dateToIntArray(String years, String months, String days)

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/main/java/org/apache/tajo/engine/planner/UniformRangePartition.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/UniformRangePartition.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/UniformRangePartition.java
index f6922ed..88cb061 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/UniformRangePartition.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/UniformRangePartition.java
@@ -422,10 +422,10 @@ public class UniformRangePartition extends RangePartitionAlgorithm {
           break;
         case TIMESTAMP:
           if (overflowFlag[i]) {
-            end.put(i, DatumFactory.createTimeStampFromMillis(
+            end.put(i, DatumFactory.createTimestmpDatumWithJavaMillis(
                 range.getStart().get(i).asInt8() + incs[i].longValue()));
           } else {
-            end.put(i, DatumFactory.createTimeStampFromMillis(last.get(i).asInt8() + incs[i].longValue()));
+            end.put(i, DatumFactory.createTimestmpDatumWithJavaMillis(last.get(i).asInt8() + incs[i].longValue()));
           }
           break;
         case INET4:

http://git-wip-us.apache.org/repos/asf/tajo/blob/526dca28/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
index bab6ec7..0742a80 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
@@ -26,8 +26,9 @@ import org.apache.tajo.catalog.proto.CatalogProtos;
 import org.apache.tajo.cli.InvalidStatementException;
 import org.apache.tajo.cli.ParsedResult;
 import org.apache.tajo.cli.SimpleParser;
-import org.apache.tajo.datum.NullDatum;
-import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.*;
 import org.apache.tajo.engine.json.CoreGsonHelper;
 import org.apache.tajo.engine.parser.SQLAnalyzer;
 import org.apache.tajo.engine.planner.*;
@@ -39,6 +40,7 @@ import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.storage.VTuple;
 import org.apache.tajo.util.Bytes;
 import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.datetime.DateTimeUtil;
 import org.apache.tajo.util.KeyValueSet;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -60,6 +62,10 @@ public class ExprTestBase {
   private static LogicalOptimizer optimizer;
   private static LogicalPlanVerifier annotatedPlanVerifier;
 
+  public static String getUserTimeZoneDisplay() {
+    return DateTimeUtil.getTimeZoneDisplayTime(TajoConf.getCurrentTimeZone());
+  }
+
   @BeforeClass
   public static void setUp() throws Exception {
     util = new TajoTestingCluster();
@@ -190,7 +196,16 @@ public class ExprTestBase {
       }
 
       for (int i = 0; i < expected.length; i++) {
-        assertEquals(query, expected[i], outTuple.get(i).asChars());
+        Datum datum = outTuple.get(i);
+        String outTupleAsChars;
+        if (datum.type() == Type.TIMESTAMP) {
+          outTupleAsChars = ((TimestampDatum) datum).asChars(TajoConf.getCurrentTimeZone(), true);
+        } else if (datum.type() == Type.TIME) {
+          outTupleAsChars = ((TimeDatum) datum).asChars(TajoConf.getCurrentTimeZone(), true);
+        } else {
+          outTupleAsChars = datum.asChars();
+        }
+        assertEquals(query, expected[i], outTupleAsChars);
       }
     } catch (InvalidStatementException e) {
       assertFalse(e.getMessage(), true);