You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by jd...@apache.org on 2014/10/15 04:20:43 UTC
svn commit: r1631936 - in /hive/branches/branch-0.14/serde/src:
java/org/apache/hadoop/hive/serde2/io/DateWritable.java
test/org/apache/hadoop/hive/serde2/io/TestDateWritable.java
Author: jdere
Date: Wed Oct 15 02:20:42 2014
New Revision: 1631936
URL: http://svn.apache.org/r1631936
Log:
HIVE-8102: Partitions of type 'date' behave incorrectly with daylight saving time. (Jason Dere, reviewed by Thejas Nair)
Modified:
hive/branches/branch-0.14/serde/src/java/org/apache/hadoop/hive/serde2/io/DateWritable.java
hive/branches/branch-0.14/serde/src/test/org/apache/hadoop/hive/serde2/io/TestDateWritable.java
Modified: hive/branches/branch-0.14/serde/src/java/org/apache/hadoop/hive/serde2/io/DateWritable.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/serde/src/java/org/apache/hadoop/hive/serde2/io/DateWritable.java?rev=1631936&r1=1631935&r2=1631936&view=diff
==============================================================================
--- hive/branches/branch-0.14/serde/src/java/org/apache/hadoop/hive/serde2/io/DateWritable.java (original)
+++ hive/branches/branch-0.14/serde/src/java/org/apache/hadoop/hive/serde2/io/DateWritable.java Wed Oct 15 02:20:42 2014
@@ -128,7 +128,10 @@ public class DateWritable implements Wri
public static long daysToMillis(int d) {
// Convert from day offset to ms in UTC, then apply local timezone offset.
long millisUtc = d * MILLIS_PER_DAY;
- return millisUtc - LOCAL_TIMEZONE.get().getOffset(millisUtc);
+ long tmp = millisUtc - LOCAL_TIMEZONE.get().getOffset(millisUtc);
+ // Between millisUtc and tmp, the time zone offset may have changed due to DST.
+ // Look up the offset again.
+ return millisUtc - LOCAL_TIMEZONE.get().getOffset(tmp);
}
public static int dateToDays(Date d) {
Modified: hive/branches/branch-0.14/serde/src/test/org/apache/hadoop/hive/serde2/io/TestDateWritable.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/serde/src/test/org/apache/hadoop/hive/serde2/io/TestDateWritable.java?rev=1631936&r1=1631935&r2=1631936&view=diff
==============================================================================
--- hive/branches/branch-0.14/serde/src/test/org/apache/hadoop/hive/serde2/io/TestDateWritable.java (original)
+++ hive/branches/branch-0.14/serde/src/test/org/apache/hadoop/hive/serde2/io/TestDateWritable.java Wed Oct 15 02:20:42 2014
@@ -10,6 +10,12 @@ import java.sql.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
public class TestDateWritable {
@@ -135,4 +141,61 @@ public class TestDateWritable {
private static String getRandomDateString() {
return dateStrings[(int) (Math.random() * 365)];
}
+
+ public static class DateTestCallable implements Callable<String> {
+ public DateTestCallable() {
+ }
+
+ @Override
+ public String call() throws Exception {
+ // Iterate through each day of the year, make sure Date/DateWritable match
+ Date originalDate = Date.valueOf("2014-01-01");
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeInMillis(originalDate.getTime());
+ for (int idx = 0; idx < 365; ++idx) {
+ originalDate = new Date(cal.getTimeInMillis());
+ // Make sure originalDate is at midnight in the local time zone,
+ // since DateWritable will generate dates at that time.
+ originalDate = Date.valueOf(originalDate.toString());
+ DateWritable dateWritable = new DateWritable(originalDate);
+ if (!originalDate.equals(dateWritable.get())) {
+ return originalDate.toString();
+ }
+ cal.add(Calendar.DAY_OF_YEAR, 1);
+ }
+ // Success!
+ return null;
+ }
+ }
+
+ @Test
+ public void testDaylightSavingsTime() throws InterruptedException, ExecutionException {
+ String[] timeZones = {
+ "GMT",
+ "UTC",
+ "America/Godthab",
+ "America/Los_Angeles",
+ "Asia/Jerusalem",
+ "Australia/Melbourne",
+ "Europe/London",
+ // time zones with half hour boundaries
+ "America/St_Johns",
+ "Asia/Tehran",
+ };
+
+ for (String timeZone: timeZones) {
+ TimeZone previousDefault = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone(timeZone));
+ assertEquals("Default timezone should now be " + timeZone,
+ timeZone, TimeZone.getDefault().getID());
+ ExecutorService threadPool = Executors.newFixedThreadPool(1);
+ try {
+ Future<String> future = threadPool.submit(new DateTestCallable());
+ String result = future.get();
+ assertNull("Failed at timezone " + timeZone + ", date " + result, result);
+ } finally {
+ threadPool.shutdown(); TimeZone.setDefault(previousDefault);
+ }
+ }
+ }
}